Willkommen zu RoboHELP. Klicken Sie aufThema (Strg+T), um Ihr erstes Hilfethema hinzuzufügen.


Dynamische Linkbibliotheken (DLLs)

Siehe auch

Eine DLL (dynamic link library) ist ein ausführbares Programm-Modul mit der Extension .DLL, das Code oder  Ressourcen enthält, die von anderen DLLs oder Programmen verwendet werden. In der Windows-Umgebung erlauben DLLs mehreren Anwendungen, Code und Ressourcen zu teilen.

Das einer DLL ähnlichste Konzept in Object Pascal ist eine Unit. Routinen in Units werden beim Linken in das Programm eingefügt („statisch gelinkt"), wohingegen DLL-Routinen in einer separaten Datei untergebracht sind und zur Laufzeit verfügbar gemacht werden („dynamisch gelinkt").

DLLs erlauben mehreren Anwendungsprogrammen eine einzelne Kopie einer gemeinsamen Routine zu teilen. Die .DLL-Datei muß sich dazu im selben Verzeichnis befinden wie das Programm zur Laufzeit.

Wenn das Programm in den Hauptspeicher geladen ist, linkt die Anwendung die Prozedur- und Funktions-Aufrufe des Programms dynamisch auf die Aufsetzpunkte des Programms in der DLL.

Hinweis:	DLLs können ausschließlich Prozeduren und Funktionen exportieren.

Weitere Informationen zum Einsatz von DLLs können Sie unter den folgenden Stichworten erhalten:

Zugriff auf Routinen in DLLs

Erstellen von DLLs


Siehe auch

Funktionsaufrufe

Import-Units


Zugriff auf Routinen in DLLs

Siehe auch	Bespiel

Es gibt zwei Möglichkeiten, auf eine Routine zuzugreifen oder sie aufzurufen, die in einer DLL gespeichert ist:

Verwenden Sie eine Externe Deklaration in Ihrem Programm (statisch importieren oder implizit laden).

Die Verwendung einer externen (external) Deklaration für einen statischen DLL-Import bewirkt, daß die DLL geladen wird bevor die Ausführung des Programms beginnt. In diesem Falle können Sie den Namen der DLL nicht während der Laufzeit verändern. Ihr Programm kann nicht ausgeführt werden, wenn es einer DLL erfordert, die zur Laufzeit nicht verfügbar ist.

Verwenden Sie GetProcAddress und LoadLibrary WinAPI-Aufrufe, um Prozedurzeiger in Ihrem Programm zu initialisieren (dynamischer Import oder explizites Laden).

Die Verwendung von GetProcAddress und LoadLibrary (diese beiden müssen gemeinsam verwendet werden) zur Importierung einer DLL ermöglicht dem Programm die Kontrolle darüber, welche Datei momentan gelanden ist. Zum Beispiel sind alle Windows-Gerätetreiber DLLs mit derselben Schnittstelle, sorgen intern jedoch für spezifische Hardware-Funktionalitäten. Programme können die DLLs für die Gerätetreiber verwenden, ohne daß sie etwas über die zugrundeliegende Hardware wissen müssen. Mit einem dynamischen Import kann Ihr Programm, auch wenn LoadLibrary eine DLL nicht finden kann, den Ablauf fortsetzen.

Obwohl eine DLL Variablen besitzen kann, ist es nicht möglich, diese in andere Module zu importieren. Jeder Zugriff auf die Variablen einer DLL muß über eine prozedurale Schnittstelle vorgenommen werden.

Wenn Sie ein Programm compilieren, daß eine DLL einsetzt, muß die DLL nicht present sein, da der Compiler ihre Präsent nicht überprüft.

Falls Sie Ihre eigenen DLLs erstellen, müssen diese separat compiliert werden.

Import von Routinen

In importierten Prozeduren und Funktionen nimmt der Befehl external den Platz der Deklaration und der Anweisungen ein.

Object Pascal importiert Prozeduren und Funktionen auf drei Weisen:

über den Namen

über einen neuen Namen

über einen Ordinalwert

Über den Namen

Wenn Sie eine Routine einer DLL ohne Index oder Name-Klausel importieren, wird die Prozedur oder Funktion explizit über den Namen importiert.

Der Name ist der Bezeichner, der Prozedur oder Funktion mit der gleichen Schreibweise.

Wenn eine Namensklausel angegeben ist, wird die Prozedur oder Funktion mit einem vom Bezeichner verschiedenen Namen importiert.

Hinweis:	Sowohl der Name der DLL, der nach dem Schlüsselwort external angegeben ist als auch der neue Name, der in einer Name-Klausel angegeben wird, müssen keine String-Literale sein. Jeder konstante String-Ausdruck ist erlaubt.

Über einen neuen Namen

Wenn Sie eine Routine einer DLL mit einer name-Klausel importieren, wird die Prozedur oder Funktion mit einem anderen Namen als dem Bezeichner importiert.

Über einen ordinalen Wert

Wenn Sie eine Routine einer DLL mit einer index-Klausel importieren, geschieht dies mit Hilfe eines Ordinalwertes.

Der Import über Ordinalzahlen verkürzt die Ladezeit des Moduls, weil Windows den Namen nicht in der Namenstabelle der DLL suchen muß. Bei der in einer Index-Klausel angegebenen Ordinalzahl kann es sich um einen beliebigen konstanten Ganzzahlausdruck handeln.


Siehe auch

Import-Units

DLLs erstellen


Beispiele

Beispiel für den Import von Routinen über den Namen

Beispiel für den Import von Routinen über einen neuen Namen

Beispiel für den Import von Routinen über einen ordinalen Wert


Beispiel

{ Das folgende Beispiel importiert die Prozedur ImportByName aus testlib.dll unter Verwendung des Namens 'ImportByName'. }

procedure ImportByName; external 'testlib.dll';


Beispiel

{ Das folgende Beispiel importiert die Prozedur ImportByNewName aus testlib.dll unter Verwendung des Namens 'RealName'. }

procedure ImportByNewName; external 'testlib.dll' name 'RealName';


Beispiel

{ Das folgende Beispiel importiert die Prozedur ImportByOrdinal als fünften Eintrittspunkt in testlib.dll. }

procedure ImportByOrdinal; external 'testlib.dll' index 5;


Import-Units

Sie können Deklarationen importierter Prozeduren und Funktionen direkt in das Programm schreiben, das sie importiert. Sie werden allerdings normalerweise in einer Import-Unit zusammengefaßt, die Deklarationen aller Prozeduren und Funktionen in einer DLL enthält, zusammen mit allen Konstanten und Typen, die für den Zugriff auf die DLL notwendig sind.

Um eine Import-Unit zu verwenden,

fügen Sie sie zur Uses-Klausel der aufrufenden Unit hinzu.

Import-Units sind für den Zugriff auf eine DLL nicht unbedingt erforderlich, vereinfachen aber den Umgang mit Projekten, die viele DLLs verwenden. Beim Ändern einer DLL muß dann nur die Import-Unit angepaßt werden.

Wenn Sie ein Programm compilieren, daß eine DLL einsetzt, muß die DLL nicht present sein, da der Compiler ihre Präsent nicht überprüft. Wenn das Programm jedoch ausgeführt wird, muß die DLL sich im selben Verzeichnis befinden wie die ausführbare Datei.

Falls Sie Ihre eigenen DLLs erstellen, müssen diese separat compiliert werden.


DLLs erstellen

Siehe auch	Beispiel

Die Struktur einer Object Pascal-DLL entspricht der eines Programms, nur steht anstatt der program-Kopfzeile eine library-Kopfzeile.

Die library-Kopfzeile weist den Object Pascal-Compiler an, eine ausführbare Datei mit der Kennzeichnung .DLL anstatt .EXE zu erzeugen.

Wenn Prozeduren und Funktionen von einer DLL exportiert werden sollen, werden sie häufig mit dem Befehl stdcall compiliert werden. Zwar ist er nicht zwingend erforderlich, doch ermöglicht der Einsatz der Aufrufskonvention stdcall  Anwendungen aus anderen Sprachen die Verwendung der DLL.

Verwenden Sie die exports-Klausel, um die Routinen tatsächlich zu exportieren.

Bibliotheken bestehen oft aus mehreren Units. In diesen Fällen enthält der Quelltext der Bibliothek oft nur eine uses-Klausel, eine exports-Klausel und den Initialisierungscode der DLL.

Globale Variablen

Globale Variablen, die in der DLL deklariert werden, sind private für die DLL.

Eine DLL kann nicht auf Variablen der Module zugreifen, die die DLL aufrufen, und es ist einer DLL nicht möglich, ihre Variablen an andere Module zu exportieren. Ein solcher Zugriff muß über eine prozedurale Schnittstelle realisiert werden.

Zwar kann eine DLL gleichzeitig von mehreren Anwendungen genutzt werden, doch erscheint es der DLL, als gäbe es nur einen Client, und jede Instanz der DLL besitzt eine eigene Menge an globalen Variablen. Damit mehrere DLLs (oder mehrere Instanzen derselben DLL) Speicher gemeinsam nutzen können, müssen sie Dateien mit Speichermapping verwenden. Nähere Informationen zu diesem Thema finden Sie in der Windows API-Dokumentation.


Beispiel

{Das folgende Beispiel implementiert eine sehr einfache DLL mit zwei exportierten Funktionen:}

library MinMax;

{ Die Prozedurdirektive stdcall exportiert Min und Max mit einer von anderen Sprachen unterstützten Aufrufskonvention. }

function Min(X, Y: Integer): Integer; stdcall;

  begin

    if X < Y then Min := X else Min := Y;

  end;

function Max(X, Y: Integer): Integer; stdcall;

  begin

    if X > Y then Max := X else Max := Y;

  end;

{Die exports-Klausel sorgt für die tatsächliche Exportierung der zwei Routinen, indem sie für jede von ihnen für einen optionalen Wert sorgt}

exports

  Min index 1,

  Max index 2;

  begin

  end.


Siehe auch

Zugriff auf in DLLs gespeicherte Routinen

DLLs und die Unit System

Import-Units

Initialisierungscode für Bibliotheken

Laufzeitfehler in DLLs

Der Shared Memory Manager

Die Variable DLLProc


Library-Initialisierungscode
Code zur Initialisierung von Bibliotheken

Beispiel 	Schreiben von DLLs

Der Anweisungsteil einer Bibliothek richtet den Initialisierungscode ein. Dieser wird einmal ausgeführt, wenn die Bibliothek geladen wird.

Der Initialisierungscode einer Bibliothek führt üblicherweise Aktionen aus, wie die Registrierung der Fensterklassen der Fensterprozeduren, die in der Bibliothek enthalten sind und setzt die Anfangswerte der globalen Variablen der Bibliothek. Zudem kann der Initialisierungscode einer Bibliothek eine Exit-Logik installieren, wozu die Variable ExitProc verwendet wird. Die Exit-Logik wird ausgeführt, wenn das Betriebssystem die Bibliothek aus dem Speicher entfernt.

Der Initialisierungscode einer Bibliothek kann eine Fehlerbedingung durch Zuweisung eines anderen Wertes als Null an die ExitCode-Variable melden. ExitCode wird in der System-Unit deklariert und wird mit 1 voreingestellt, was bedeutet, daß die Initialisierung erfolgreich verlaufen ist. Falls der Initialisierungscode die ExitCode-Variable auf einen Wert ungleich Null setzt, wird die DLL aus dem Speicher entfernt und die aufrufende Anwendung darauf aufmerksam gemacht, daß die DLL nicht mehr geladen ist.

Hinweis	Tritt bei der Ausführung des Initialisierungscodes einer Bibliothek eine unbearbeitete Fehlerbedingung auf, so wird die aufrufende Anwendung darauf aufmerksam gemacht, daß die DLL nicht geladen wurde.

Wird eine DLL aus dem Speicher entfernt, führt der Object Pascal-Compiler die Exit-Logik der DLL aus, indem die Adresse, die in der ExitProc-Variable gespeichert ist, solange aufgerufen wird, bis ExitProc den Wert nil annimmt. Da dies in gleicher Weise funktioniert wie die Behandlung von Exit-Prozeduren in Object Pascal-Programmen, können Sie sowohl in Programmen als auch in Bibliotheken dieselbe Exit-Logik anwenden.

Hinweis	Die Initialisierungs-Teile aller von einer Anwendung oder Bibliothek verwendeten Units werden immer vor dem Anweisungs-Teil der Anwendung oder Bibliothek ausgeführt. Ebenso werden die Unit-Finalization-Teile nach der von einer Anwendung oder Bibliothek installierten Exit-Logik ausgeführt (Unit-Finalization-Teile verwenden sogar die Variable ExitProc, um sich selbst zu installieren).


Beispiel

{Der folgende Code ist ein Beispiel einer Bibliothek mit Initialisierungscode und einer Terminierungsprozedur:}

library Test;

var

  SaveExit: Pointer;

procedure LibExit;

begin

  :

  { Exit-Code der Bibliothek }

  :

  ExitProc := SaveExit;	{ Wiederherstellen der Kette der Exit-Prozedur }

end;

begin

  :

  { Intitialisierungs-Code der Bibliothek }

  :

  SaveExit := ExitProc;	{ Speichern der Kette der Exit-Prozedur }

  ExitProc := @LibExit;	{ Installation der LibExit-Exit-Prozedur  }

end.


DLLs und das System Unit
DLLs und die System-Unit

Siehe auch

The Boolesche Variable IsLibrary kann zur Bestimmung verwendet werden, ob im Kontext einer Anwendung oder Bibliothek Code ausgeführt wird. IsLibrary ist bei einer Anwendung immer Falsch, in einer Bibliothek immer Wahr.

Während der Dauer einer DLL enthält die Variable HInstance den Instanzen-Handle der.

Die Variable CmdLine ist in einer DLL immer nil.


Siehe auch

Erstellen von DLLs


Laufzeitfehler in DLLs
Ausnahmen und Laufzeitfehler in DLLs

Siehe auch

Tritt in einer DLL eine Ausnahme auf und wird nicht behandelt, wird sie aus der DLL weitergegeben. Ist die aufrufende Anwendung oder DLL selbst in Object Pascal geschrieben, so kann die Ausnahme mit einer normalen try...except-Anweisung behandelt werden.

Wurde die aufrufende Anwendung oder DLL in einer anderen Programmiersprache geschrieben, so kann die Ausnahme als Fehler des Betzriebssystems mit dem Fehlercode $0EEDFACE behandelt werden. Der erste Eintrag im Feld ExceptionInformation des Betriebssystem-Fehlerrecords enthält die Fehleradresse, der zweite eine Referenz auf das Object Pascal-Ausnahmeobjekt.

Verwendet eine DLL die Unit SysUtils nicht, so ist die Fehlerunterstützung von Object Pascal deaktiviert. In diesem Fall wird die Anwendung, die die DLL aufgerufen hat, beendet, wenn ein Laufzeitfehler auftritt. Da eine DLL keine Möglichkeit hat, zu erkennen, ob sie von einer Object Pascal-Anwendung oder einer anderen Anwendung, die in einer anderen Programmiersprache entwickelt wurde, aufgerufen wurde, kann die DLL die Terminierungs-Prozedur nicht starten bevor die Anwendung beendet wird. Die Anwendung wird einfach abgebrochen und aus dem Speicher entfernt. Aus diesem Grunde versichern Sie sich, daß ausreichende Maßnahmen innerhalb des DLL-Codes getroffen werden, die diese Fehler verhindern.

Falls ein Laufzeitfehler innerhalb einer DLL auftritt, ist es am sichersten, Windows ganz zu verlassen.


Siehe auch

Fehlerbehandlung

Erstellen von DLLs


Der Shared Memory Manager

DLLS

Exportiert eine DLL Prozeduren oder Funktionen, die lange Zeichenketten als Parameter oder Funktionsergebnisse liefern (sei es direkt oder verschachtelt in Records oder Objekten), müssen die DLL und ihre Client-Anwendungen (oder DLLs) alle die Unit ShareMem verwenden. Gleiches gilt, wenn ein Modul (Anwendung oder DLL) Speicher mit New oder GetMem zuweist, der durch einen Aufruf von Dispose oder FreeMem in einem anderen Modul freigegeben wurde.

Bei ShareMem handelt es sich um die Interface-Unit für den Shared Memory Manager DELPHIMM.DLL, der zusammen mit den Anwendungen und/oder Bibliotheken, die ShareMem verwenden, eingesetzt werden. Verwendet eine Anwendung oder DLL ShareMem, so wird die Speicherverwaltung der Anwendung oder DLL durch den Memory Manager in DELPHIMM.DLL ersetzt, wodurch es möglich wird, dynamisch zugewiesenen Speicher gemeinsam mit mehreren Modulen zu nutzen.

Wird die Unit ShareMem von einer Anwendung oder Bibliothek verwendet, sollte sie in der uses-Anweisung der Anwendung oder Bibliothek als erste Unit aufgeführt sein.


Die Variable DLLProc

Siehe auch	Erstellen von DLLs

Die in der System-Unit definierte Variable DLLProc ermöglicht einer DLL, alle Aufrufe des Betriebssystems an den Eintrittspunkt der DLL zu überwachen. Diese Funktion ist für gewöhnlich nur dann von Interesse, wenn die DLL Multi-Threading unterstützt.

Um Aufrufe des Betriebssystems an den Eintrittspunkt einer DLL zu überwachen, wird die Adresse einer Prozedur mit folgender Parameterliste der Variable DLLProc zugewiesen.

procedure DLLHandler(Reason: Integer);

Wird die DLL-Prozedur aufgerufen, enthält der Parameter Reason parameter einen der folgenden (in der Unit Windows definierten) Werte:

DLL_PROCESS_DETACH	Gibt an, daß die DLL aus dem Adressraum des aufrufenden Prozesses entfernt wird, da der Prozeß entweder regulär beendet oder FreeLibrary aufgerufen wurde.
DLL_THREAD_ATTACH	Gibt an, daß der aktuelle Prozeß einen neuen Thread erzeugt.
DLL_THREAD_DETACH	Zeigt an, daß ein Thread regulär beendet wird.


Siehe auch


Schreiben stabiler Anwendungen

Object Pascal stellt durch einen besonderen Mechanismus sicher, daß Ihre Anwendungen robust sind. Das bedeutet, daß Fehler konsistent behandelt werden und die Anwendung - wenn möglich - sich von Fehlern holen oder ohne Verlust von Daten oder Ressourcen schließen können, wenn es erforderlich sein sollte.

Fehlerbedingungen in Object Pascal  werden durch Exceptions angezeigt.

Um zur Erzeugung sicherer Anwendungen Exceptions einzusetzen, müssen Sie über Kenntnisse der folgenden Themenbereiche verfügen:

Code-Blöcke schützen

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Stille Exceptions

Definieren eigener Exceptions


Code-Blöcke schützen

Siehe auch

Damit Ihre Anwendungen robust sind, muß Ihr Code Exceptions als solche erkennen, wenn sie auftreten und auf sie reagieren. Wenn Sie keine bestimmte Reaktion festlegen, wird die Anwendung ein Meldungsfenster mit einer Beschreibung des Fehlers anzeigen. Es ist also Ihre Aufgabe, die Stellen zu erkennen, an denen Fehler auftreten könnten und Reaktionen darauf zu definieren. Dies ist besonders an solchen Stellen wichtig, an denen Fehler zum Verlust von Daten oder Systemressourcen führen können.

Wenn Sie eine Reaktion auf eine Exception erzeugen, bezieht sich diese auf Code-Blöcke. Handelt es sich um eine Reihe von Anweisungen, die alle die gleiche Reaktion auf Fehler zeigen sollen, können Sie diese als Block zusammenfassen und Fehlerreaktionen definieren, die den gesamten Block betreffen.

Blöcke mit bestimmten Reaktionen auf Exceptions nennt man geschützte Blöcke, da sie vor Fehlern schützen können, die andernfalls die Anwendung beenden oder Daten beschädigen könnten.

Um Code-Blöcke zu schützen, müssen Sie Kenntnisse der folgenden Vorgänge besitzen

Reagieren auf Exceptions

Exceptions und der Fluß der Ausführung

Reaktionen auf Exceptions verschachteln


Siehe auch

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Stumme Exceptions

Definieren eigener Exceptions


Reagieren auf Exceptions

Siehe auch

Beim Auftreten einer Fehlerbedingung wird durch die Anwendung eine Exception ausgelöst, d.h. es wird ein Exception-Objekt erzeugt. Sobald die Exception ausgelöst wurde, kann Ihre Anwendung Freigabe-Code ausführen, die Exception behandeln oder beides.

Ausführen von Freigabe-Code

Die einfachste Methode, auf eine Exception zu reagieren, besteht darin, sicherzustellen, daß Freigabe-Code ausgeführt wird. Diese Art von Reaktion korrigiert nicht die Bedingung, die den Fehler verursacht hat, stellt jedoch sicher, daß die Anwendung ihre Umgebung nicht in einen instabilen Zustand versetzt.

Typischerweise verwenden Sie diese Reaktion, um sicherzustellen, daß die Anwendung zugewiesene Ressourcen unabhängig davon, ob ein Fehler aufgetreten ist, wieder freigibt.

Behandlung der Exception

Eine Exception zu behandeln bedeutet, eine bestimmte Reaktion auf eine bestimmte Art von Exception hervorzurufen. Hierdurch wird die Fehlerbedingung gelöscht und das Exception-Objekt entfernt, so daß die Anwendung in der Ausführung fortfahren kann.

Normalerweise werden Exception-Behandlungsroutinen definiert, um Anwendungen auch nach Auftreten eines Fehlers die weitere Ausführung zu ermöglichen. Exception-Typen, die Sie eventuell behandeln, sind unter anderem der Versuch, nicht vorhandene Dateien zu öffnen, auf einen vollen Datenträger zu schreiben oder Berechnungen außerhalb der zulässigen Wertebereiche durchzuführen. Einige, wie beispielsweise „Datei nicht gefunden", können einfach korrigiert und der Code kann neu ausgeführt werden, während andere-beispielsweise Speicherplatzprobleme--für die Anwendung oder den Anwender schwieriger zu beheben sind.


Siehe auch

Auslösen einer Exception

Reaktionen auf Exceptions verschachteln

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Stumme Exceptions

Definieren eigener Exceptions


Exceptions und der Fluß der Ausführung

Siehe auch	Beispiel

Object Pascal macht es Ihnen einfach, die Fehlerbehandlung in Anwendungen einzubeziehen, da Exceptions den normalen Fluß Ihres Codes nicht behindern. Indem Sie Fehlerprüfung und -behandlung aus dem Hauptfluß Ihrer Algorithmen auslagern, können Exceptions den Code, den Sie schreiben, sogar vereinfachen.

Wenn Sie einen geschützten Block, deklarieren, definieren Sie bestimmte Reaktionen auf Exceptions, die innerhalb dieses Blocks auftreten können. Tritt eine Exception in diesem Block auf, springt die Ausführung sofort auf die Reaktion, die Sie definiert haben, und verläßt dann diesen Block.


Beispiel

Diese Codezeilen zeigen e Verwendung eines geschützten Blocks. Tritt innerhalb des geschützten Blocks eine Exception auf, springt die Ausführung auf den Exception-Behandlungsabschnitt und gibt einen Warnton aus. Die Ausführung wird außerhalb des Blocks wiederaufgenommen.

...
try	{ geschützten Block beginnen }
  Font.Name := 'Courier';	{ wenn eine Exception auftritt... }

  Font.Size := 24;	{ ...in einer dieser Anweisungen... }

  Color := clBlue;

except	{ ...springt die Ausführung hierhin }
  on Exception do MessageBeep(0);	{ dies behandelt jede Exception durch einen Warnton }

end;
...	{ die Ausführung wird hier, außerhalb des geschützten Blocks, wiederaufgenommen }


Siehe auch

Reagieren auf Exceptions

Reaktionen auf Exceptions verschachteln


Reaktionen auf Exceptions verschachteln

Siehe auch

Ihr Code definiert Reaktionen auf Exceptions, die innerhalb von Blöcken auftreten. Da in Pascal Blöcke in andere Blöcke verschachtelt werden können, können Sie Reaktionen sogar innerhalb von Blöcken, die ihrerseits bereits Reaktionen anpassen, gemäß Ihren Wünschen gestalten.

Im einfachsten Fall können Sie beispielsweise eine Ressourcen-Zuweisung schützen und innerhalb dieses geschützten Blocks Blöcke definieren, die andere Ressourcen zuweisen und schützen. Schematisch könnte dies folgendermaßen aussehen:

Außerdem können Sie verschachtelte Blöcke verwenden, um die lokale Behandlung bestimmter Exceptions zu definieren, die die Behandlung des umgebenden Blocks überschreibt. Schematisch sieht dies ungefähr so aus:

Außerdem können Sie verschiedene Arten von Blöcken zur Behandlung von Exceptions mischen und Ressourcen-Schutz in Blöcken zur Behandlung von Exceptions verschachteln und umgekehrt.


Siehe auch

Reagieren auf Exceptions

Exceptions und der Fluß der Ausführung

Reichweite der Exception-Behandlungsroutinen


Schützen von Ressourcen-Zuweisungen (try..finally-Block)
Ressourcen-Zuweisungen schützen

Siehe auch

Ein Schlüssel zu robusten Anwendungen liegt darin, daß Sie sicherstellen, daß zugewiesene Ressourcen wieder freigegeben werden, und zwar auch, wenn eine Exception auftritt. Wenn Ihre Anwendung beispielsweise Speicher zuweist, müssen Sie dafür sorgen, daß sie diesen Speicher dann auch wieder freigibt. Wenn sie eine Datei öffnet, müssen Sie sicherstellen, daß sie diese Datei später auch wieder schließt.

Bitte beachten Sie, daß Exceptions nicht nur aus Ihrem Code herrühren. Ein Aufruf z.B. einer RTL-Routine oder einer anderen Komponente in Ihrer Anwendung kann eine Exception auslösen. Ihr Code muß sicherstellen, daß beim Auftreten dieser Bedingungen zugewiesene Ressourcen freigegeben werden.

Um Ressourcen wirksam zu schützen, sollten Sie mit den folgenden Themen vertraut sein:

Welche Arten von Ressourcen müssen geschützt werden?

Erzeugen eines Ressourcen-Schutzblocks


Siehe auch

Code-Blöcke schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Stumme Exceptions

Definieren eigener Exceptions


Welche Arten von Ressourcen müssen geschützt werden?

Siehe auch	Beispiel

Unter normalen Umständen können Sie sicherstellen, daß eine Anwendung zugewiesene Speicherressourcen freigibt, indem Sie Code sowohl für die Zuweisung als auch für die Freigabe schreiben. Wenn jedoch Exceptions auftreten, müssen Sie dafür Sorge tragen, daß die Anwendung auch weiterhin den Code zur Freigabe der Ressourcen ausführt.

Die folgenden Ressourcen sollten Sie zum Beispiel immer freigeben

Dateien

Speicher

Windows-Ressourcen

Objekte


Beispiel

Die folgende Ereignisbehandlungsroutine weist Speicher zu, erzeugt dann einen Fehler und führt dadurch niemals den Code aus, der den Speicher freigibt:

procedure TForm1.Button1Click(Sender: TComponent);

var
  APointer: Pointer;
  AnInteger, ADividend: Integer;

begin
  ADividend := 0;

  GetMem(APointer, 1024);	{ 1K Speicher zuweisen }

  AnInteger := 10 div ADividend;	{ dies erzeugt einen Fehler }

  FreeMem(APointer, 1024);	{ dies wird nie erreicht }
end;

Obwohl die meisten Fehler nicht so offensichtlich sind, veranschaulicht das Beispiel einen wichtigen Punkt: Beim Auftreten des Fehlers Division durch Null springt die Ausführung aus dem Block, und die Anweisung FreeMemkann den Speicher nicht mehr freigeben.

Um garantieren zu können, daß FreeMem den durch GetMem zugewiesenen Speicher auch wieder freigibt, müssen Sie den Code in einen Ressourcen-Schutzbloc schreiben.


Siehe auch

Erzeugen eines Ressourcen-Schutzblocks


Erzeugen eines Ressourcen-Schutzblocks

Siehe auch	Beispiel

Um sicherzustellen, daß Sie zugewiesene Ressourcen freigeben, auch wenn eine Exception auftritt, betten Sie den Code, der Ressourcen verwendet, in einen geschützten Block ein. Der Code, der die Ressourcen freigibt, steht dabei an einer besonderen Stelle des Blocks. Schematisch sieht eine typische geschützte Ressourcenzuweisung so aus:

{ Ressource zuweisen }

try
  { Anweisungen, die die Ressource verwenden }

finally
  { Ressource freigeben }

end;

Das Besondere des Blocks try..finally liegt darin, daß die Anwendung alle Anweisungen im Abschnitt finally des Blocks immer ausführt - sogar dann, wenn eine Exception im geschützten Block aufgetreten ist. Löst Code aus dem Abschnitt try des Blocks (oder eine beliebige Routine, die vom Code im Abschnitt try aufgerufen wird) eine Exception aus, springt die Ausführung sofort in den Abschnitt finally, der Freigabe-Code genannt wird. Tritt keine Exception auf, wird der Freigabe-Code in der normalen Reihenfolge nach allen Anweisungen im Abschnitt try ausgeführt.

Die Anweisungen des abschließenden Codes sind nicht davon abhängig, daß eine Exception auftritt. Wenn keine der Anweisungen im Abschnitt try eine Exception auslöst, läuft die Ausführung durch den abschließenden Code hindurch weiter.

Hinweis:	Ein Ressourcen-Schutzblock behandelt die Exception nicht. Der abschließende Code besitzt nicht einmal Informationen darüber, ob überhaupt eine Exception aufgetreten ist. Er kann daher auch nicht bestimmen, ob er eine Exception behandeln muß. Tritt eine Exception in einem Ressourcen-Schutzblock auf, wird zuerst der abschließende Code ausgeführt und der Block dann verlassen. Die ausgelöste Exception bleibt bestehen. Der Block, der den geschützten Block enthält, kann anschließend auf die Exception reagieren.


Beispiel

Hier eine Ereignisbehandlungsroutine, die Speicher zuweist und einen Fehler erzeugt, aber dennoch den zugewiesenen Speicher wieder freigibt:

procedure TForm1.Button1Click(Sender: TComponent);

var
  APointer: Pointer;
  AnInteger, ADividend: Integer;

begin
  ADividend := 0;

  GetMem(APointer, 1024);	{ 1K Speicher zuweisen }

  try
    AnInteger := 10 div ADividend;	{ dies erzeugt einen Fehler }

  finally
    FreeMem(APointer, 1024);	{ die Ausführung wird trotz des Fehlers
hier wiederaufgenommen }

  end;

end;


Siehe auch

Welche Arten von Ressourcen müssen geschützt werden?


Behandlung von RTL-Exceptions

Siehe auch

Wenn Sie Code schreiben, der Routinen der Laufzeitbibliothek (RTL) wie beispielsweise mathematische Funktionen oder Dateiverwaltungsprozeduren aufruft, meldet die RTL Ihrer Anwendung Fehler in Form von Exceptions zurück. Standardmäßig führen RTL-Exceptions zu einer Meldung, die die Anwendung dem Anwender anzeigt. Sie können Ihre eigenen Exception-Behandlungsroutinen erzeugen, um RTL-Exceptions auf andere Weise zu behandeln.

Es gibt aber auch stille Exceptions, die in Vopreinstellung keine Meldung ausgeben.

Um RTL-Exceptions wirkungsvoll zu behandeln, müssen Sie mit den folgenden Themengebieten vertraut sein:

Welche RTL-Exceptions gibt es?

Erzeugen einer Exception-Behandlungsroutine

Standard-Exception-Behandlungsroutinen verfügbar machen

Klassen von Exceptions behandeln

Nochmaliges Auslösen einer Exception


Siehe auch

Code-Blöcke schützen

Ressourcen-Zuweisungen schützen

Behandlung von Komponenten-Exceptions

Stumme Exceptions

Definieren eigener Exceptions


Welche RTL-Exceptions gibt es?

Siehe auch

Die Exceptions der Laufzeitbibliothek sind in der Unit SysUtils definiert. Sie sind alle von einem generischen Exception-Objekttyp namens Exception abgeleitet. Exception stellt den String für die Meldung zur Verfügung, die RTL-Exceptions standardmäßig anzeigen.

Die RTL löst 7 verschiedene Arten von Exceptions aus:

Eingabe-/Ausgabe-Exceptions

Heap-Exceptions

Integerwert-Exceptions

Gleitkomma-Exceptions

Typumwandlungs-Exceptions

Umwandlungs-exceptions

Hardware-Exceptions


Eingabe-/Ausgabe-Exceptions

Eingabe-/Ausgabe- (I/O) Exceptions können von Zeit zu Zeit auftreten, wenn die RTL versucht, auf Dateien oder I/O-Geräte zuzugreifen. Die meisten I/O-Exceptions beziehen sich auf Fehlercodes, die von Windows oder DOS beim Zugriff auf eine Datei zurückgegeben werden.

Die Unit SysUtils definiert eine generische Eingabe-/Ausgabe-Exception namens EInOutErrorSie können auf dieses Feld in der Instanz des Exception-Objekts zugreifen, um zu bestimmen, wie die Exception zu behandeln ist.


Heap-Exceptions

Heap-Exceptions können eventuell dann auftreten, wenn Sie versuchen, dynamischen Speicher zuzuweisen oder auf ihn zuzugreifen. Die Unit SysUtils definiert 2 Heap-Exceptions namens EOutOfMemory und EInvalidPointer. zeigt die einzelnen Heap-Exceptions. Jede stammt direkt von Exeption ab:

Exception	Bedeutung

EOutOfMemory	Nicht genug Platz auf dem Heap, um die angegebene Operation zu beenden.

EInvalidPointer


Integerwert-Exceptions

Integerwert-Exceptions können auftreten, wenn Sie Operationen mit Audrücken vom Typ Integer durchführen. Die Unit SysUtils definiert eine generische Integerwert-Exception namens EIntError. Die RTL löst niemals EIntError aus, stellt aber eine Basis zur Verfügung, von der alle einzelnen Integerwert-Exceptions abgeleitet sind.

zeigt die einzelnen Integerwert-Exceptions. Jede ist direkt von EIntError abgeleitet.

Exception	Bedeutung

EDivByZero	Versuchte Division durch Null.

ERangeError	Zahl oder Ausdruck außerhalb des Wertebereichs.

EIntOverflow	Überlauf Integeroperation.


Gleitkomma-Exceptions

Gleitkomma-Exceptions können auftreten, wenn Sie Operationen mit Realtype-Ausdrücken durchführen. Die Unit SysUtils definiert eine generische Gleitkomma-Exception namens EMathError. Die RTL löst niemals einen EMathError aus, stellt aber eine Basis zur Verfügung, von der aus alle einzelnen Gleitkomma-Exceptions abgeleitet sind.

zeigt die einzelnen Gleitkomma-Exceptions. Jede ist direkt von EMathError abgeleitet:

Exception	Bedeutung

EInvalidOp

EZeroDivide	Versuch der Division durch Null.

EOverflow	Überlauf Gleitkommaoperation.

EUnderflow	Unterlauf Gleitkommaoperation.


Typumwandlungs-Exceptions

Typumwandlungs-Exceptions können beim Versuch auftreten, ein Objekt Typumwandlung unter Verwendung des Operators as in einen anderen Typ umzuwandeln. Sie Unit SysUtils definiert eine Exception namens EInvalidCast, die die RTL auslöst, wenn die gewünschte Typumwandlung nicht zulässig ist.


Umwandlungs-Exceptions

Umwandlungs-Exceptions können auftreten, wenn Daten mit Funktionen wie IntToStr, StrToInt, StrToFloat und so weiter aus einem Format in ein anderes konvertiert werden. Die Unit SysUtils definiert eine Exception mit dem Namen EConvertError, die von der RTL ausgelöst wird, wenn die Funktion die ihr übergebenen Daten nicht umwandeln kann.


Hardware-Exceptions

Hardware Exceptions können in 2 Arten von Situationen auftreten: Entweder entdeckt der Prozessor einen Fehler, den er nicht behandeln kann, oder die Anwendung erzeugt absichtlich einen Interrupt, um die Ausführung zu unterbrechen. Die Behandlung von Hardware-Exceptions ist nicht in DLLs compiliert, sondern nur in eigenständigen Anwendungen.

Die Unit SysUtils definiert eine generische Hardware-Exception namens EProcessorException. Die RTL löst niemals eine EProcessorException aus, sondern stellt eine Basis zur Verfügung, von der die einzelnen Hardware-Exceptions abgeleitet werden.

Die folgende Tabelle zeigt die einzelnen Hardware-Exceptions.

Exception	Bedeutung

EFault	Basis-Exception-Objekt, von dem alle Fehlerobjekte abgeleitet sind.

EGPFault	Allgemeine Schutzverletzung, normalerweise von einem nicht initialisierten Zeiger oder Objekt verursacht.

EStackFault	Nicht zulässiger Zugriff auf das Stack-Segment des Prozessors.

EPageFault	Die Windows-Speicherverwaltung konnte die Auslagerungsdatei nicht korrekt verwenden.

EInvalidOpCode	Der Prozessor ist auf einen nicht definierten Befehl gestoßen. Meistens bedeutet dies, daß der Prozessor versucht hat, Daten oder nicht initialisierten Speicher auszuführen.

EBreakpoint	Die Anwendung hat einen Haltepunkt-Interrupt erzeugt.

ESingleStep	Die Anwendung hat einen Einzelschritt-Interrupt erzeugt.

Sie sollten eigentlich nur selten auf die Fehler-Exceptions stoßen, da es sich bei ihnen um ein ernsthaftes Versagen der Betriebsumgebung handelt. Anders ist dies bei allgemeinen Schutzverletzungen. Die Haltepunkt- und Einzelschritt-Exceptions werden im allgemeinen innerhalb des integrierten Debugger behandelt.


Siehe auch

Erzeugen einer Exception-Behandlungsroutine

Standard-Exception-Behandlungsroutinen verfügbar machen

Klassen von Exceptions behandeln

Nochmaliges Auslösen einer Exception


Erzeugen von Exception-Behandlungsroutinen (try..except-Block)
Erzeugen einer Exception-Behandlungsroutine

Siehe auch	Beispiel

Eine Exception-Behandlungsroutine besteht aus Code, der eine oder mehrere bestimmte Exceptions behandelt, die innerhalb eines geschützten Code-Blocks auftreten.

Um eine Exception-Behandlungsroutine zu definieren, betten Sie den Code, den Sie schützen wollen, in einen Block zur Behandlung von Exceptions ein und geben die Anweisungen zur Behandlung der Exception im Abschnitt except des Blocks an. Schematisch sieht ein typischer Block zu Behandlung von Exceptions folgendermaßen aus:

try
  { statements you want to protect }

except
  { exception-handling statements }

end;

Die Anwendung führt die Anweisungen im Abschnitt except nur dann aus, wenn während der Ausführung der Anweisungen im Abschnitt try eine Exception aufgetreten ist. Die Ausführung der Anweisungen im Abschnitt try beinhaltet Routinen die durch Code im Abschnitt try aufgerufen werden. Wenn also Code im Abschnitt try eine Routine aufruft, die nicht ihre eigene Exception-Behandlungsroutine definiert, kehrt die Ausführung zum Block für die Behandlung von Exceptions zurück, der dann die Exception behandelt.

Löst eine Anweisung im Abschnitt try eine Exception aus, springt die Ausführung sofort zum Abschnitt except und arbeitet die angegebenen Anweisungen zur Behandlung von Exceptions oder Exception-Behandlungsroutinen Schritt für Schritt ab, bis eine Behandlungsroutine gefunden wird, die auf die aktuelle Exception anwendbar ist.

Sobald die Anwendung eine Exception-Behandlungsroutine findet, die die Exception behandelt, führt sie die Anweisung aus und entfernt automatisch das Exception-Objekt. Die Ausführung wird am Ende des aktuellen Blocks wiederaufgenommen.


Siehe auch

Verwenden der Exception-Instanz

Reichweite der Exception-Behandlungsroutinen

Standard-Exception-Behandlungsroutinen verfügbar machen

Klassen von Exceptions behandeln

Nochmaliges Auslösen einer Exception


Anweisungen zur Behandlung von Exceptions

Siehe auch	Beispiel

Jede Anweisung im Abschnitt except eines try..except-Blocks definiert Code, der ausgeführt werden muß, um eine bestimmte Art von Exception zu behandeln. Formal sehen diese Anweisungen zur Behandlung von Exceptions folgendermaßen aus:

on <Exception-Typ> do <Anweisung>;


Beispiel

Sie können  eine Exception-Behandlungsroutine für die Division durch Null definieren, um ein Standardergebnis zu erhalten:

function GetAverage(Sum, NumberOfItems: Integer): Integer;
begin

  try
    Result := Sum div NumberOfItems;

  except
    on EDivByZero do Result := 0;

  end;

end;

Dies ist viel klarer, als bei jedem Aufruf der Funktion auf Null testen zu müssen. Hier eine entsprechende Funktion, die die Vorteile von Exceptions nicht ausnutzt:

function GetAverage(Sum, NumberOfItems: Integer): Integer;
begin

  if NumberOfItems <> 0 then
    Result := Sum div NumberOfItems
  else Result := 0;

end;

Der Unterschied zwischen diesen 2 Funktionen spiegelt genau den Unterschied zwischen Programmierung mit Exceptions und Programmierung ohne Exceptions wieder. Dieses Beispiel ist zwar recht einfach, man kann sich jedoch auch eine komplexere Berechnung mit vielen hundert Schritten vorstellen, bei der jeder Schritt zu einem Fehler führen würde, wenn nur eine von Dutzenden von Eingaben ungültig ist.

Durch die Verwendung von Exceptions können Sie den „normalen" Ausdruck Ihres Algorithmus festlegen und für die Ausnahmefälle vorsorgen, in denen er nicht zutrifft. Ohne Exceptions müssen Sie jedesmal untersuchen, ob Sie den nächsten Schritt in der Berechnung auch wirklich ausführen dürfen.


Siehe auch

Verwenden der Exception-Instanz

Reichweite der Exception-Behandlungsroutinen


Verwenden der Exception-Instanz

Siehe auch	Beispiel

In den meisten Fällen benötigt eine Exception-Behandlungsroutine keine weiteren Informationen zu einer Exception außer der Kenntnis ihres Typs. Daher sind die Anweisungen, die on..do folgen, auch nur bezüglich des Typs der Exception spezifisch. In gewissen Fällen müssen Sie jedoch eventuell auf einige der Informationen, die in der Exception-Instanz enthalten sind, zurückgreifen.

Um bestimmte Informationen über eine Exception-Instanz in einer Exception-Behandlungsroutine zu lesen, verwenden Sie eine spezielle Variante von on..do, die Ihnen den Zugriff auf die Exception-Instanz ermöglicht. Für diese besondere Form ist es erforderlich, daß Sie eine temporäre Variable verfügbar machen, die die Instanz enthält.

Die temporäre Variable (E in diesem Beispiel) ist von dem Typ, der nach dem Doppelpunkt (EInvalidOperation in diesem Beispiel) angegeben wird. Sie können den Operator as verwenden, um bei Bedarf eine Typumwandlung der Exception in einen spezifischeren Typ durchzuführen.

Hinweis:	Entfernen Sie niemals das temporäre Exception-Objekt. Die Behandlung einer Exception entfernt das Exception-Objekt automatisch. Wenn Sie das Objekt hingegen selbst entfernen, wird die Anwendung nochmals versuchen, das Objekt zu entfernen und einen schwerwiegenden Anwendungsfehler erzeugen.


Beispiel

Wenn Sie ein neues Projekt erzeugen, das nur ein Formular enthält, können Sie dem Formular eine Bildlaufleiste und einen Befehlsschalter hinzufügen. Klicken Sie den Schalter zweimal an und ergänzen Sie seine Klickereignisbehandlungsroutine um die folgende Zeile:

ScrollBar1.Max := ScrollBar1.Min - 1;

Diese Zeile löst eine Exception aus, da der Maximalwert einer Bildlaufleiste immer größer als der Minimalwert sein muß. Die Standard-Exception-Behandlungsroutine für die Anwendung öffnet ein Dialogfenster, das die Meldung in dem Exception-Objekt enthält. Sie können die Behandlung von Exceptions in dieser Exception-Behandlungsroutine überschreiben und Ihr eigenes Meldungsfenster erzeugen, das den Meldungs-String der Exception enthält:

try
  ScrollBar1.Max := ScrollBar1.Min - 1;

except
  on E: EInvalidOperation do
    MessageDlg('Ignoring exception: ' + E.Message, mtInformation, [mbOK], 0);

end;


Siehe auch

Anweisungen zur Behandlung von Exceptions

Reichweite der Exception-Behandlungsroutinen


Reichweite der Exception-Behandlungsroutinen

Siehe auch

Sie müssen keine Behandlungsroutinen für jede Art von Exception in jedem Block zur Verfügung stellen. Sie müssen nur Behandlungsroutinen für diejenigen Exceptions, die Sie innerhalb des betreffenden Blocks besonders behandeln wollen, verfügbar machen.

Behandelt ein Block eine bestimmte Exception nicht, verläßt die Ausführung diesen Block und geht mit noch immer ausgelöster Exception zu demjenigen Block zurück, der diesen Block enthält (oder zu dem Code, der den Block aufgerufen hat). Dieser Prozeß wird mit immer größerer Reichweite wiederholt, bis entweder die Ausführung den äußersten Umfang der Anwendung erreicht hat oder bis ein Block auf irgendeiner Ebene die Exception behandelt.


Siehe auch

Anweisungen zur Behandlung von Exceptions

Verwenden der Exception-Instanz


Standard-Exception-Behandlungsroutinen verfügbar machen

Siehe auch

Sie können eine einzelne Standard-Exception-Behandlungsroutine zur Verfügung stellen, die alle Exceptions behandelt, für die Sie keine besonderen Behandlungsroutinen verfügbar gemacht haben. Zu diesem Zweck fügen Sie dem Abschnitt except des Blocks zur Behandlung von Exceptions einen Abschnitt else hinzu:

try
  { Anweisungen }

except
  on ESomething do	 { besonderer Code zum Behandeln von Exceptions };

  else	 { Code zur Standardbehandlung von Exceptions };
end;

Das Hinzufügen einer Standard-Exception-Behandlung zu einem Block garantiert, daß der Block jede Exception auf irgendeine Art behandelt und damit jegliche Behandlung aus dem enthaltenden Block überschreibt.

Achtung!:	Sie sollten diese allumfassende Exception-Behandlungsroutine besser niemals einsetzen. Die Anweisung else behandelt alle Exceptions; auch die, von denen Sie nichts wissen. Ihr Code sollte grundsätzlich nur die Exceptions behandeln, bei denen Sie tatsächlich auch sicher sind, wie sie behandelt werden müssen. In anderen Fällen ist es besser, Freigabe-Code auszuführen und die Behandlung solchem Code zu überlassen, der mehr Informationen über die Exception und die Art ihrer Behandlung besitzt.


Siehe auch

Erzeugen einer Exception-Behandlungsroutine

Klassen von Exceptions behandeln

Nochmaliges Auslösen einer Exception


Klassen von Exceptions behandeln

Siehe auch	Beispiel

Da Exception-Objekte Teil einer Hierarchie sind, können Sie Behandlungsroutinen für ganze Bereiche der Hierarchie angeben, indem Sie eine Behandlungsroutine für die Exception-Klasse, von der dieser Teil der Hierarchie abgeleitet ist, zur Verfügung stellen.


Beispiel

Der folgende Block stellt schematisch ein Beispiel dar, das alle Integerwert-Exceptions besonders behandelt:

try
  { Anweisungen, die Integerwert-Operationen durchführen }

except
  on EIntError do { besondere Behandlung für Integerwert-Fehler };
end;

Sie können auch weiterhin besondere Behandlungsroutinen für spezifischere Exceptions angeben. Sie müssen diese Behandlungsroutinen jedoch oberhalb der generischen Behandlungsroutine einsetzen, da die Anwendung die Behandlungsroutinen in der Reihenfolge ihres Auftretens durchsucht und die erste passende Behandlungsroutine, die sie findet, ausführt.

Dieser Block ermöglicht beispielsweise eine besondere Behandlung für Bereichsfehler sowie eine davon abweichende Berhandlung aller anderen Integerwert-Fehler:

try
  { Anweisungen, die Integerberechnungen durchführen }

except
  on  do { };

  on  do { Behandlung der anderen Integerwertfehler };
end;

Beachten Sie die Reihenfolge der Behandlungsroutinen: würde die Behandlungsroutine für  vor der Behandlungsroutine für  stehen, würde die Ausführung nie bis zu der besonderen Behandlungsroutine für gelangen.


Siehe auch

Erzeugen einer Exception-Behandlungsroutine

Standard-Exception-Behandlungsroutinen verfügbar machen

Nochmaliges Auslösen einer Exception


Nochmaliges Auslösen einer Exception

Siehe auch	Beispiel

Wenn Sie eine Exception lokal behandeln, wollen Sie vielleicht manchmal die Behandlung innerhalb des umschließenden Blocks eher vergrößern als ersetzen. Wenn Ihre lokale Behandlungsroutine die Behandlung abgeschlossen hat, entfernt sie natürlich die Exception-Instanz, und die Behandlungsroutine des umschließenden Blocks kann nicht mehr aktiv werden. Sie können jedoch die Behandlungsroutine daran hindern, die Exception zu entfernen und damit der umschließenden Behandlungsroutine die Möglichkeit zum Reagieren geben.

Wenn Code im Abschnitt { Anweisungen } eine ESomething-Exception auslöst, wird nur die Behandlungsroutine im äußeren Abschnitt except ausgeführt. Löst hingegen Code im Abschnitt { besondere Anweisungen } ESomething aus, wird die Behandlungsroutine im inneren Abschnitt except ausgeführt, gefolgt von der allgemeineren Behandlung des äußeren Abschnitts except.

Indem Sie Exceptions erneut auslösen, können Sie auf einfache Weise eine besondere Behandlung für Exceptions in bestimmten Situationen erreichen, ohne die bestehenden Behandlungsroutinen zu verlieren (oder zu duplizieren)


Beispiel

Wenn eine Exception auftritt, wollen Sie für den Anwender wahrscheinlich eine Meldung ausgeben und anschließend mit der Standardbehandlung fortfahren. Hierzu definieren Sie eine lokale Exception-Behandlungsroutine, die die Meldung anzeigt und danach aufruft. Man nennt dies die Exception nochmals auslösen. Das folgende Beispiel illustriert dieses Verfahren:

try
  { Anweisungen }

  try
    { besondere Anweisungen }

  except
    on ESomething do
    begin
      { Behandlung nur der besonderen Anweisungen }

      raise;	{ nochmaliges Auslösen der Exception }
    end;
  end;
except
  on ESomething do ...;                                     { Behandlung für alle Fälle }
end:


Siehe auch

Erzeugen einer Exception-Behandlungsroutine

Standard-Exception-Behandlungsroutinen verfügbar machen

Klassen von Exceptions behandeln


Behandlung von Komponenten-Exceptions

Siehe auch	Beispiel

Die Komponenten von Object Pascal lösen Exceptions aus, um Fehlerbedingungen anzuzeigen. Die meisten Komponenten-Exceptions geben Programmierfehler an, die sonst zu einem Laufzeitfehler führen würden. Die Mechanismen, mit denen Komponenten-Exceptions behandelt werden, unterscheiden sich nicht von der Behandlung von RTL-Exceptions.

Eine häufige Fehlerursache bei Komponenten liegt in Bereichsfehlern bei indizierten Eigenschaften. Wenn ein Listenfenster beispielsweise 3 Einträge in seiner Liste besitzt (0..2) und Ihre Anwendung versucht, auf Eintrag Nummer 3 zuzugreifen, löst das Listenfenster eine Exception „Index außerhalb des Bereichs" aus.


Beispiel

Die folgende Ereignisbehandlungsroutine enthält eine Exception-Behandlungsroutine, die dem Anwender einen unzulässigen Index-Zugriff in einem Listenfenster meldet:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Items.Add('ein String');	{ Listenfenster String hinzufügen }

  ListBox1.Items.Add('ein weiterer String');	{ weiteren String hinzufügen... }

  ListBox1.Items.Add('noch ein String');	{ ...und einen dritten String }

  try
    Caption := ListBox1.Items[3];	{ Formulartitel auf vierten String }

{ im Listenfenster setzen }

  except
    on EListError do
      MessageDlg('Listenfenster enthält weniger als vier Strings', mtWarning, [mbOK], 0);

  end;
end;

Wenn Sie einmal auf den Schalter klicken, besitzt das Listenfenster nur 3 Strings, und der Zugriff auf den 4. String (Items[3]) löst eine Exception aus. Wenn Sie nochmals klicken, werden der Liste weitere Strings hinzugefügt. Damit wird keine Exception mehr verursacht.


Siehe auch

Code-Blöcke schützen

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Definieren eigener Exceptions


Stille Exceptions

Siehe auch	Beispiel

Object Pascal-Anwendungen behandeln die meisten Exceptions, die nicht gesondert von Ihrem Programm-Code behandelt werden, durch Anzeigen eines Meldungsfensters, das den Botschafts-String des Exception-Objekts anzeigt. Sie können darüber hinaus „stille" Exceptions definieren, die die Anwendung nicht standardmäßig zum Anzeigen der Fehlermeldung veranlassen.

Stille Exceptions sind nützlich, wenn Sie eine Exception nicht behandeln möchten, die Operation aber trotzdem abbrechen wollen. Das Abbrechen einer Operation ist ein ähnlicher Vorgang wie das Abbrechen eines Blocks mit den Prozeduren Break oder Exit, kann sich aber auf meherere geschachtelte Ebenen von Blöcken erstrecken.

Stille Exceptions sind alle aus dem Standard-Exceptions-Typ EAbort abgeleitet. Die Standard-Exception-Behandlungsroutine für Object Pascal-Anwendungen zeigt das Fehlermeldungs-Dialogfenster für alle Exceptions an, die sie erreichen, mit Ausnahme der aus EAbort abgeleiteten.

Es gibt eine Abkürzung für das Auslösenstiller Exceptions. Statt das Objekt von Hand zu konstruieren, können Sie die Prozedur Abort aufrufen. Abort löst automatisch eine EAbort-Exception aus, die die aktuell ausgeführte Operation abbricht, ohne eine Fehlermeldung auszugeben.


Beispiel

Der folgende Quelltext zeigt ein einfaches Beispiel für das Abbrechen einer Operation. Fügen Sie in einem Formular, das einen Schalter und ein leeres Listenfenster enthält, folgenden Quelltext in das OnClick-Ereignis des Schalters ein:

procedure TForm1.Button1Click(Sender: TObject);

var
  I: Integer;

begin

  for I := 1 to 10 do	{ Schleife zehnmal ausführen }
  begin

    ListBox1.Items.Add(IntToStr(I));	{ eine Zahl in die Liste einfügen }

    if I = 7 then Abort;	{ nach dem siebten Mal abbrechen }

  end;
end;


Siehe auch

Code-Blöcke schützen

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Definieren eigener Exceptions


Definieren eigener Exceptions

Siehe auch

Neben dem Schutz Ihres Codes vor Exceptions, die von der Laufzeit-Bibliothek und verschiedenen Komponenten erzeugt werden, können Sie die gleichen Verfahren auch einsetzen, um außergewöhnliche Bedingungen in Ihrem eigenen Code zu verwalten.

Um in Ihrem Code Exceptions einzusetzen, müssen Sie die folgenden Schritte durchführen:

Deklarieren eines Exception-Objekttyps

Auslösen einer Exception


Siehe auch

Code-Blöcke schützen

Ressourcen-Zuweisungen schützen

Behandlung von RTL-Exceptions

Behandlung von Komponenten-Exceptions

Stumme Exceptions


Deklarieren eines Exception-Objekttyps

Siehe auch	Beispiel

Da es sich bei Exceptions um Objekte handelt, ist das Definieren einer neuen Art von Exception ebenso einfach wie das Deklarieren eines neuen Objekttyps. Obwohl Sie jede beliebige Objektinstanz als Exception auslösen können, behandeln die Standard-Exception-Behandlungsroutinen nur diejenigen Exceptions, die von Exception abgeleitet sind.

Es ist daher sinnvoll, alle neuen Exception-Typen von Exception oder einer der anderen Standard-Exceptions abzuleiten. Auf diese Art und Weise wird beim Auslösen einer neuen Exception in einem Code-Block, der nicht durch eine besondere Exception-Behandlungsroutine für diese Exception geschützt ist, die Exception stattdessen durch eine der Standardbehandlungsroutinen behandelt.


Beispiel

Nehmen Sie beispielsweise an, daß die folgende Deklaration gegeben ist:

type
  EMyException = class(Exception);

Wenn Sie EMyException auslösen, aber keine besondere Behandlungsroutine für EMyException verfügbar machen, wird eine Behandlungsroutine für Exception (oder eine Standardbehandlungsroutine) dennoch die Behandlung durchführen. Da die Standardbehandlung für Exception den Namen der ausgelösten Exception anzeigt, können Sie so wenigstens feststellen, daß Ihre neue Exception ausgelöst wurde.


Siehe auch

Auslösen einer Exception


Auslösen einer Exception

Siehe auch	Beispiel

Um eine Fehlerbedingung in einer Anwendung anzuzeigen, können Sie eine raise auslösen; exception dieser Vorgang umfaßt das Konstruieren einer Instanz dieses Typs und das Aufrufen des reservierten Worts raise.

Zum Auslösen einer Exception rufen Sie das reservierte Wort raise auf, gefolgt von einer Instanz eines Exception-Objekts.

Wenn eine Exception-Behandlungsroutine dann die eigentlichje Behandlung der Exception durchführt, entfernt sie abschließend die Exception-Instanz; Sie brauchen das also niemals selbst zu tun.

Setzen der Exception-Adresse

Das Auslösen einer Exception setzt die Variable ErrorAddr in der Unit System auf die Adresse, an der die Anwendung die Exception ausgelöst hat. Sie können ErrorAddr in Ihren Exception-Behandlungsroutinen referenzieren, um beispielsweise dem Benutzer mitzuteilen, an welcher Stelle der Fehler aufgetreten ist. Sie können außerdem für ErrorAddr einen Wert festlegen, wenn Sie eine Exception auslösen.

Zum Festlegen einer Fehleradresse für eine Exception setzen Sie nach der Exception-Instanz das reservierte Wort at ein, gefolgt von einem Adreßausdruck, wie etwa einem Bezeichner.


Beispiele

Zum Beispiel können Sie in folgender Deklaration

type
  EPasswordInvalid = class(Exception);

jederzeit eine Exception „Paßwort ungültig" auslösen, indem Sie raise mit einer Instanz von EPasswordInvalid aufrufen, etwa so:

if Password <> CorrectPassword then
  raise EPasswordInvalid.Create('Ungültiges Paßwort eingegeben');


Siehe auch

Deklarieren eines Exception-Objekttyps

Nochmaliges Auslösen einer Exception


Gültigkeitsbereich

Siehe auch	Beispiel	Sprachdefinition

Der Gültigkeitsbereich eines Bezeichners innerhalb eines Programms oder einer Unit gibt an, ob der Bezeichner von anderen Prozeduren und Funktionen im Programm oder der Unit benutzt werden kann oder nicht.

Der Gültigkeitsbereich kann entweder lokal oder global sein. Lokale Bezeichner sind nur für die Routinen und Deklarationen sichtbar, die in dem Block enthalten sind, in welchem der Bezeichner deklariert wird.

Globale Bezeichner werden im Interface-Abschnitt der Unit deklariert und sind für alle Routinen und Deklarationen innerhalb dieser Unit sichtbar.

Beim Entwurf der Programmstruktur, beachten Sie die drei Gültigkeitsbereichsregeln:

Jeder Bezeichner hat nur in dem Block eine Bedeutung, in dem er deklariert wird. Innerhalb des Blocks ist er nach der Stelle bekannt, an der er deklariert wird.

Wenn ein globaler Bezeichner innerhalb eines Blocks neu definiert wird, erhält die innerste (die am tiefsten geschachtelte) Definition von der Stelle der Deklaration Vorrang bis zum Ende des Blocks.

Wenn Prozeduren rekursiv aufgerufen werden, zeigt eine Referenz einer globalen Variable immer auf die Instanz dieser Variable im zuletzt erfolgten Prozeduraufruf.

Es gibt verschiedene Arten von Gültigkeitsbereichen:

Gültigkeitsbereich von Blöcken

Gültigkeitsbereich von Objekttypen

Sichbarkeit von Objekttype

Gültigkeitsbereich von Units

Gültigkeitsbereich von Interface- und Standardbezeichnern


Siehe auch

Globale und lokale Variablen

Gültigkeitsbereichsregeln


Gültigkeitsbereich von Objekttypen

Siehe auch	Gültigkeitsbereich

Der Gültigkeitsbereich eines Elements, das innerhalb eines Objekttyps deklariert wurde, erstreckt sich von der Stelle der Deklaration bis zum Ende der Objektdefinition und über jeden Prozedur-, Funktions-, Konstruktor- und Destruktor-Block, in dem Methoden des Objekttyps und seiner Nachkommen implementiert werden.

Weil Elemente eines Objekttyps für Routinen außerhalb der Definition sichtbar sind, muß die Schreibweise der Komponentenbezeichner innerhalb des strukturierten Typs, seiner Nachkommen und Methoden eindeutig sein.

Es gibt drei Teile der Definition eines Objekttyps. Die Sichtbarkeit eines Elements wird davon bestimmt, in welchem Teil Sie es deklarieren.

Im public-Teil der Deklaration ist der Gültigkeitsbereich von Elementen nicht besonders eingeschränkt.

Im private-Teil der Deklaration eines Objekttyps, sind Elemente auf das Modul eingeschränkt (Program oder Unit, das die Deklaration des Objekttyps enthält. Private Elemente können ausschließlich innerhalb des Moduls benutzt werden, das die Deklaration des Objekttyps enthält. Außerhalb dieses Moduls sind sie unbekannt und nicht zugänglich.

Im protected-Teil einer Objekttyp-Deklaration, ....

Der Gültigkeitsbereich dieser Komponentenbezeichner umfaßt Feldbezeichner und with-Anweisungen, die mit Variablenreferenzen des gegebenen Records oder Objekttyps arbeiten. Der Gültigkeitsbereich von Komponenten des Objekttyps erstreckt sich über alle Nachkommen des Objekttyps und alle Blöcke von Methodendeklarationen des Objekttyps.


Siehe auch

Gültigkeitsbereich von Blöcken

Gültigkeitsbereichsregeln

Gültigkeitsbereich von Interface- und Standardbezeichnern

Gültigkeitsbereich von Units


Gültigkeitsbereich von Blöcken

Siehe auch	Beispiel	Gültigkeitsbereich

In einem Block, beginnt der Gültigkeitsbereich eines Bezeichners oder Labels am Ort der Deklaration und reicht bis zum Ende des aktuellen Blocks, einschließlich aller darin geschachtelten Blöcke.

Wenn Sie einen Bezeichner innerhalb eines geschachtelten Blocks überschreiben, erstreckt sich der Gültigkeitsbereich des neuen Bezeichners nur über den geschachtelten Block und nicht außerhalb.

Ein Typbezeichner ist nur lokal in dem Block gültig, in dem die Typdeklaration erfolgt. Rekursive Deklarationen sind nur bei Zeigertypen möglich, sonst darf eine Deklaration keine Teile von sich selber enthalten.


Beispiel

program Outer;	{ Beginn des äußeren Gültigkeitsbereichs }

type

  I = Integer;	{ Definiere I als Ganzzahl }

var

  T: I;	{ Definiere T als Ganzzahlvariable }

procedure Inner;	{ Beginn des inneren Gültigkeitsbereichs }

type

  T = I;	{ Neudefinition: T als Ganzzahl }

var

  I: T;	{ Neudefinition: I als Ganzzahlvariable }

begin

  I := 1;

end;	{ Ende des inneren Gültigkeitsbereichs }

begin

  T := !;

end.	{ Ende des äußeren Gültigkeitsbereichs }


Siehe auch

Gültigkeitsbereich von Units

Gültigkeitsbereichsregeln


Gültigkeitsbereich von Records

Siehe auch	Gültigkeitsbereich

Der Gültigkeitsbereich eines Feldbezeichners, der in einer Record-Typdefinition deklariert wird, erstreckt sich von der Stelle der Deklaration bis zum Ende der Record-Typdefinition.

Der Gültigkeitsbereich des Feldbezeichners umfaßt auch andere Feldbezeichner und with Anweisungen, die mit Variablenreferenzen des entsprechenden Records arbeiten.


Siehe auch

Record-Typen

Gültigkeitsbereichsregeln


Gültigkeitsbereich von Units

Siehe auch	Gültigkeitsbereich

Ein Bezeichner, der im interface-Teil einer Unit deklariert wurde, ist für andere Programme und Units verfügbar, die in ihren uses-Anweisungen die Unit spezifizieren, die den Bezeichner enthält.

Wenn mehr als eine Unit in der uses-Anweisung aufgeführt ist, gelten folgende Regeln:

Der Gültigkeitsbereich jeder Unit umfaßt alle folgenden Units und das Programm (oder die Unit), die die uses-Anweisung enthält.

Die erste Unit definiert den äußersten Gültigkeitsbereich, die letzte Unit den innersten Gültigkeitsbereich. Wenn ein Bezeichner in mehr als einer Unit deklariert wird, spezifiziert eine unqualifizierte Referenz auf den Bezeichner diejenige Instanz, die von der letzten Unit deklariert wurde. Um eine Instanz zu spezifizieren, die in einer anderen Unit deklariert wurde, verwenden Sie einen qualifizierten Bezeichner.

Hinweis:	Der Gültigkeitsbereich der System-Unit ist global, so daß jedes Programm Zugriff auf die Standardbezeichner von Object Pascal hat. Die System-Unit muß nicht in der uses-Anweisung angegeben werden.


Siehe auch

Qualifizierer

Gültigkeitsbereichsregeln


Beispiel

program scope2;

var

  A: integer;	{Globale Variable}

procedure SetA;

var

  A :  integer;	{Erzeugt eine lokale Variable A}

begin

  A := 4

end;	{Zerstört lokale Variable A}

begin

  A := 3;	{Weist globaler Variable A einen Wert zu}

  SetA;	{Ruft Prozedur SetA auf}

    Writeln(A)	{Wert von A = 3 -- nicht 4!)

end.


Gültigkeitsbereichsregeln

Siehe auch	Gültigkeitsbereich

Das Vorhandensein eines Bezeichners oder eines Labels in einer Deklaration definiert den Bezeichner oder das Label. Jedesmal wenn der Bezeichner oder das Label wieder auftritt, muß es sich innerhalb des Gültigkeitsbereichs dieser Deklaration befinden.

Der Gültigkeitsbereich eines Bezeichners oder eines Labels erstreckt sich von seiner Deklaration bis zum Ende des aktuellen Blocks, und umfaßt alle Blöcke, die im aktuellen Block eingeschlossen sind.

Der Gültigkeitsbereich erstreckt sich auch über alle Nachkommen des Objekttyps, einschließlich der Feldbezeichner und with-Anweisungen, die mit Variablenreferenzen auf den angegebenen Objekttyp arbeiten.

Die folgenden drei Regeln bilden die Ausnahmen:

1.	Neudeklaration in einem untergeordneten Block:

Angenommen, daß Außen ein Block ist, der einen anderen Block Innen einschließt. Wenn Außen und Innen beide einen Bezeichner mit dem selben Namen haben (zum Beispiel J), dann kann Innen nur auf das J zugreifen, das von Innen deklariert wurde. Ebenso kann Außen nur auf das J zugreifen, das von Außen deklariert wurde.

2.	Ort der Deklaration in einem Block:

Bezeichner und Labels müssen deklariert sein, bevor sie verwendet werden können.

Die Deklaration eines Bezeichners oder Labels muß erfolgen, bevor ein Bezeichner oder Label im Programmtext verwendet wird. Nur der Basistyp vom Typ Pointer darf ein noch nicht deklarierter Bezeichner sein. Dieser Bezeichner muß aber später im selben Deklarationsteil deklariert werden, in dem der Pointer-Typ verwendet wird.

3.	Neudeklaration im selben Block:

Grundsätzlich dürfen Bezeichner und Labels auf der obersten Ebene eines Blocks nur einmal deklariert werden, es sei denn, sie sind in einem enthaltenen Block oder in der Feldliste eines Records deklariert.

Ein Record-Feldbezeichner wird innerhalb des Record-Typs deklariert. Sie haben nur zusammen mit einem Verweis auf eine Variable dieses Record-Typs Bedeutung.

Man kann also einen Bezeichner eines Feldes im selben Block (in derselben Schreibweise) erneut deklarieren, jedoch nicht auf derselben Ebene desselben Record-Typs.

Ein Bezeichner, der einmal deklariert wurde, kann aber als Feldbezeichner im selben Block neu deklariert werden.


Siehe auch

Gültigkeitsbereich von Blöcken

Gültigkeitsbereich von Interface- und Standardbezeichnern

Gültigkeitsbereich von Objekttypen

Gültigkeitsbereich von Records

Gültigkeitsbereich von Units


Gültigkeitsbereich von Interface- und Standardbezeichnern

Siehe auch	Gültigkeitsbereich

Programme oder Units, die uses-Klauseln enthalten, haben Zugriff auf die Bezeichner, die im Interface-Teil der dort genannten Units deklariert sind.

Jede in einer uses-Anweisung angebene Unit erfordert einen neuen Gültigkeitsbereich, der die verwendeten Units und das Programm oder die Unit mit der uses-Anweisung umfaßt.

Die erste Unit in einer uses-Anweisung stellt den äußersten, die letzte Unit den innersten Gültigkeitsbereich dar.

Wenn zwei oder mehr Units denselben Bezeichner deklarieren, wählt eine unqualifizierte Referenz auf den Bezeichner die in der letzten Unit in der uses-Anweisung deklarierte Instanz.


Siehe auch

Gültigkeitsbereich von Blöcken

Gültigkeitsbereich von Objekttypen

Gültigkeitsbereichsregeln

Gültigkeitsbereich von Units

Uses-Anweisung


Compiler-Befehle
Compiler-Befehle: Definition und Verwendung

Siehe auch	Compiler-Befehle

Compiler-Befehle ermöglichen Ihnen, das voreingestellte Verhalten des Compilers zu beeinflussen. Compiler-Befehle sind Kommentare, die einer bestimmten Syntax genügen müssen und überall dort verwendet werden dürfen, wo Kommentare erlaubt sind. Ihr Gültigkeitsbereich kann global und lokal sein, aber nicht alle Befehle können in sowohl global als auch lokal verwendet werden.

Lokale Befehle können an jeder Stelle des Programms bzw. der Unit stehen; sie beeinflussen nur einen Teil des Compiliervorgangs.

Globale Befehle müssen vor dem Deklarationsteil des zu compilierenden Programms bzw. der zu compilierenden Unit stehen; sie beeinflussen den gesamten Compiliervorgang.

Es gibt drei Formen von Compiler-Befehlen:

Schalterbefehle

Mit einem Schalterbefehl werden bestimmte Funktionen des Compilers ein- oder ausgeschaltet. Auf den Namen des Befehls mit einem Buchstaben Länge folgt dementsprechend ein Minuszeichnen (-) oder ein Pluszeichen (+). Bei längeren Versionen wird „On“ oder „Off“ angegeben. Es können mehrere Schalterbefehle gruppiert werden, indem Sie durch Kommata (keine Leerzeichen) voneinander getrennt werden, z.B:

{$F+,R+,D-}

Parameterbefehle

Parameterbefehle übergeben dem Compiler Informationen wie z.B. Dateinamen, Text oder Speicherspezifikationen. Zwischen dem Parameterbefehlswort und den Parametern muß sich mindestens ein Leerzeichen befinden, wie z.B.:

{$I TYPES.INC}

{$L YOUR.DOC}

Bedingte Befehle und Symbole

Bedingte Befehle steuern, ausgehend von der Auswertung eines dem Befehl nachgestellten Symbols, die Compilierung bestimmter Teile des Quelltextes. Sie können sowohl eigene Symbole verwenden als auch die vordefinierten Symbole, die Object Pascal zur Verfügung stellt. Bedingte Befehle müssen innerhalb des Codes spezifiziert werden.


Siehe auch

Bedingte Compilierung: Befehle und Symbole

Verwendung von bedingten Befehlen


Die vordefinierten bedingten Symbole sind: CONSOLE, WIN32 und CPU386 sowie VER90.


Alphabetische Liste der Compiler-Befehle

Siehe auch

Hier finden Sie eine alphabetische Liste aller Compiler-Befehle, die vom Object Pascal-Compiler unterstützt werden. Über diese Liste können Sie direkt auf eine komplette Definition jedes Befehls gelangen.

Befehl	Art	Bedeutung

$A	Schalter	Ausrichtung der Variablen im Speicher

$ALIGN	Schalter	Ausrichtung von Daten

$APPTYPE	Parameter	Anwendungstyp

$B	Schalter	Auswertung boolescher Ausdrücke

BOOLEVAL	Schalter	Boolesche Auswertung

$D	Schalter	Zusatzinformationen für den Debugger

$DEBUGINFO	Schalter	Debug Information

$D Text	Parameter	Beschreibung

$EXTENDEDSYNTAX	Schalter	Erweiterte Syntax

$H	Schalter	Long-Strings

$HINTS	Schalter	Compiler-Hinweise

$I	Schalter	Automatische Prüfung von Ein-/Ausgaben

$I Dateiname	Parameter	Include-Datei

IMAGEBASE	Parameter	Code-Image Basisadresse

$INCLUDE FileName	Parameter	Include-Datei

$IOCHECKS	Schalter	Ein-/Ausgabeprüfung

$J	Schalter	beschreibbare typisierte Konstanten

$L	Schalter	Lokale Symbole

$L Dateiname	Parameter	Einbinden von Objektdateien

LINK Dateiname	Parameter	Link Object-Datei

$LOCALSYMBOLS	Schalter	Lokale Symbolinformation

$LONGSTRINGS	Schalter	Long-Strings

$M	Schalter	Information  über den Runtime-Typ

$M StackSize	Parameter	Maximale Stackgröße

$MAXSTACKSIZE StackSize	Parameter	Maximale Stackgröße

$MINENUMSIZE	Schalter/Parameter	Aufgelistete Typgröße

$MINSTACKSIZE StackSize	Parameter	Minimale Stackgröße

$O	Schalter	Optimierung

$OPENSTRINGS	Schalter	Open-String Parameter

$OPTIMIZATION	Schalter	Optimierung

$OVERFLOWCHECKS	Schalter	Arithmetische Überlaufsprüfung

$P	Schalter	Offene String-Parameter

$Q	Schalter	Test auf arithmetischen Überlauf

$R	Schalter	Test auf Wertebereichsüberschreitung

$R Dateiname	Parameter	Ressourcen-Datei

RANGECHECKS	Schalter	Bereichsprüfung

$REFERENCEINFO	Schalter	Symbolreferenz-Information

$RESOURCE Dateiname	Parameter	Ressource-Datei

$SAFEDIVIDE	Schalter	Pentium-gerechte FDIV-Operationen

$STACKFRAMES	Schalter	Windows Stack Frame

$T	Schalter	Getypter @-Operator

TYPEDADDRESS	Schalter	Typisierter @-Operator

$TYPEINFO	Schalter	Runtime Typinformation

$U	Schalter	Pentium-gerechte FDIV Operationen

$V	Schalter	Überprüfung von Var-Strings

$VARSTRINGCHECKS	Schalter	Var-String-Prüfung

$W	Schalter	Windows-Stack-Rahmen

$WARNINGS	Schalter	Compilerwarnungen

$WRITEABLECONST	Schalter	Beschreibbare typisierte Konstanten

$X	Schalter	Erweiterte Syntax

$Y	Schalter	Symbol-Referenzinformation

$Z	Schalter	Wortgröße von Aufzählungstypen

Siehe auch

Bedingte Anweisungen: Befehle und Symbole

Definition und Verwendung von Compiler-Befehlen

Verwendung von bedingten Befehlen


Bedingte Anweisungen und Symbole
Bedingte Compilierung: Befehle und Symbole

Siehe auch

Bedingte Befehle steuern, ausgehend von der Auswertung eines dem Befehl nachgestellten Symbols, die Compilierung bestimmter Teile des Quelltextes. Sie können sowohl eigene Symbole verwenden als auch die vordefinierten Symbole, die Object Pascal zur Verfügung stellt.

Bedingter Befehl	Bedeutung

$DEFINE	Definiert ein bedingtes Symbol

$ELSE	Compiliert oder Ignoriert einen Teil des Quelltextes

$ENDIF	Ende des bedingten Abschnitts

$IFDEF	Compilierung des Quelltextes, falls der Name definiert ist

$IFNDEF	Compilierung des Quelltextes, falls der Name nicht definiert ist

$IFOPT	Compilierung des Quelltextes, falls ein Schalter in einem bestimmten Zustand ist (+ oder -)

$UNDEF	Aufhebung der Definition eines zuvor definierten bedingten Symbols

Bedingtes Symbol	Bedeutung

CONSOLE	Anwendung wird als Konsolenanwendung compiliert.

WIN32	Betriebssystemumgebung ist die Win32 API.

CPU386	CPU gehört zur 80x86-Prozessorfamilier

VER90	Compiliert abhängig von der angegebenen Version, z.B. wird Code, der durch {$IFDEF VER90} eingeleitet wird, nur dann compiliert, wenn der Compiler die Versionsnummer 9.0 hat. Der DCC32.EXE Object Pascal-Compiler, der mit C++Builder verwendet wird, ist VER93.


Siehe auch

Alphabetische Liste der Compiler-Befehle

Definition und Verwendung von Compiler-Befehlen

Verwendung bedingter Befehle


Verwendung bedingter Befehle

Siehe auch	Compiler-Befehle

Bedingte Befehle erzeugen, abhängig vom Zustand der bedingten Symbole, unterschiedlichen Code aus demselben Quelltext. Bezeichner von Object Pascal könne in bedingten Befehlen nicht eingesetzt werden.

Hinweis:	Nach der Durchführung von Änderungen an den Bedingungen sollte das Programm erneut erzeugt werden.

Es gibt zwei mögliche bedingte Konstrukte:

{$IFxxx} ... {$ENDIF}

{$IFxxx} ... {$ELSE} ... {$ENDIF}

$IF ... $ENDIF

Der von {$IFxxx} und {$ENDIF} eingeschlossene Quelltext wird nur dann übersetzt, wenn die in {$IFxxx} angegebene Bedingung zutrifft (True).

Wenn sie nicht zutrifft (False), wird er ignoriert.

$IF ... $ELSE ... $ENDIF

Der Quelltext innerhalb eines {$IFxxx} ... {$ELSE} ... {$ENDIF}-Konstrukts wird nach den folgenden Bedingungen compiliert:

Trifft die in {$IFxxx} angegebene Bedingung zu (True), wird der Quelltext zwischen {$IFxxx} und {$ELSE} übersetzt.

Trifft die in {$IFxxx} angegebene Bedingung nicht zu (False), wird der Quelltext zwischen {$ELSE} und {$ENDIF} übersetzt.

Befehle zur bedingten Compilierung dürfen bis zu einer Tiefe von 16 Ebenen geschachtelt werden.

Jede Quelltextdatei muß genauso viele {$IFxxx} wie {$ENDIF} Befehle enthalten.

$IFDEF

Bewirkt die Übersetzung des folgenden Quelltexts, wenn der bezeichnete Name definiert ist.

Syntax

{$IFDEF Name}

Innerhalb eines Textabschnitts, der von $IFDEF (oder $IFNDEF) und $ENDIF eingeschlossen wird, compiliert $ELSE den nachfolgenden Quelltext, wenn die $IFDEF (oder $IFNDEF) nicht zutrifft (False).

Falls die $IFDEF (oder $IFNDEF)-Bedingung wahr ist, wird der Quelltext nach $ELSE ignoriert.

$IFNDEF

Der nachfolgende Quelltext wird nur übersetzt, wenn der spezifizierte Name nicht definiert ist.

Syntax

{$IFNDEF Name}

$IFOPT

Bewirkt die Compilierung des nachfolgenden Quelltextes, falls der Schalter Schalter sich gegenwärtig im angebenen Zustand befindet.

Syntax

{$IFOPT Schalter}

Schalter ist der Name einer Schalteroption, gefolgt von + oder -.

Switch+	Schalter ist AN

Switch-	Schalter ist AUS


Siehe auch

$DEFINE und $UNDEF: Bedingte Symbolbefehle


DEFINE, UNDEF bedingte Symbolanweisungen
$DEFINE und $UNDEF: Bedingte Symbolbefehle

Siehe auch	Compiler-Befehle

Verwenden sie $DEFINE und $UNDEF, um bedingte Symbole zu definieren, die der Compiler vor der Compilierung auswertet. Bedingte Symbole gleichen insofern booleschen Variablen, als daß sie entweder den Wert True oder False annehmen. Sie unterliegen den Object Pascal-Bestimmungen zur Benennung von Bezeichnern, können jedoch im aktuellen Programm nicht verwendet werden, genausowenig, wie Bezeichner von Object Pascal nicht in bedingten Befehlen verwendet werden können.

$DEFINE

Definiert ein bedingtes Symbol mit dem angegebenen Namen (setzt das Symbol auf True). Der Gültigkeitsbereich bezieht sich ausschließlich auf die aktuelle Quelldatei, nicht global auf alle Quelldateien. Verwenden Sie die Befehlszeilenoption /D oder wählen Sie ** aus dem Dialog Optioenn|Projekt|Verzeichnisse/Bedingungen, um etwas für sämtliche Module zu definieren.

Syntax

{$DEFINE Name}

Innerhalb des Programms ist das definierte Symbol solange gültig, bis es in einem $UNDEF Name-Befehl auftaucht. $DEFINE Name hat keine Wirkung, falls Name bereits definiert ist.

$UNDEF

Hebt die Definition eines zuvor definierten bedingten Symbols Name auf.

Syntax

{$UNDEF Name}

Das Symbol existiert für den Rest des Compiliervorgangs nicht mehr, es sei denn, es wird erneut innerhalb eines $DEFINE-Befehls definiert. Der $UNDEF-Befehl hat keine Wirkung, falls die Definition von Name bereits aufgehoben wurde oder Name nicht definiert ist.


Siehe auch

Bezeichner

Verwendung bedingter Befehle


Vordefinierte bedingte Symbole

Siehe auch	Compiler-Befehle

Der Object Pascal-Compiler definiert die folgenden bedingten Symbole:

CONSOLE

Definiert wenn eine Anwendung als Konsolenanwendung compiliert wird.

CPU386

Zeigt an, daß der Prozessor der 80386-Prozessorfamilie oder besser angehört.

VER90

Ist immer definiert. Zeigt an, daß es sich um die Version 9.0 des Objekt Pascal-Compilers handelt. Jede Version hat entsprechende vordefinierte Symbole. So hätte Version 9.1 beispielsweise VER91 definiert, Version 9.5 wäre VER95 und so weiter.

WIN32

Gibt an, daß die Betriebssystemungebung Win32 API ist.


Siehe auch

Verwendung bedingter Befehle


Datenausrichtung { $A }, { $ALIGN }

Compiler-Befehle

Dieser Compiler-Befehl steuert die Ausrichtung of Feldern in Record Typen.

Syntax:	{$A+} or {$A-}
{$ALIGN ON} or {$ALIGN OFF}

Voreinstellung:	{A+}
{$ALIGN ON}

Gültigkeit:	Lokal

Anmerkung

Unabhängig vom Status des $A-Befehls werden Variablen und Konstanten immer auf optimalen Zugriff ausgerichtet.

AN { $A+ }, { $ALIGN ON }

Wenn Align Fields eingeschaltet ist, werden alle Felder in Record Typen, die ohne the Packed-Option deklariert sind, an Word-Grenzen ausgerichtet (an einer geraden Adresse). Falls nötig, werden ungenutzte Bytes zwischen den Variablen eingefügt, um die Ausrichtung auf Word zu erreichen.

Diese Option hat keine Wirkung bei Variablen von Bytegröße, Feldern von Record-Strukturen oder -Objekten und Elementen von Arrays. Ein Record-Feld wird nur dann auf Word ausgerichtet, wenn die Gesamtgröße aller Felder davor eine gerade Zahl ergibt.

Array-Elemente werden nur dann auf Word ausgerichtet, wenn die Größe des einzelnen Elements gerade ist.

AUS { $A-}, { $ALIGN OFF }

Wenn die Datenausrichtung ausgeschaltet ist, findet keine Ausrichtung statt.


Anwendungstyp-Direktive {$APPTYPE}
Anwendungstyp

Compiler-Befehle

Der Befehl $APPTYPE legt fest, ob eine Konsolenanwendung oder eine Anwendung mit grafischer Benutzeroberfläche erzeugt werden soll.

Syntax:	{$APPTYPE GUI}
{$APPTYPE CONSOLE}

Voreinstellung:	{$APPTYPE GUI}

Gültigkeit:	Global

Grafische Benutzeroberfläche { $APPTYPE GUI }

Im Modus {$APPTYPE GUI} erzeugt der Compiler eine Anwendung mit grafischer Benutzeroberfläche. Dies ist der Standard für eine Object Pascal-Anwendung.

Konsole { $APPTYPE CONSOLE }

Im Modus {$APPTYPE CONSOLE} erzeugt der Compiler eine Consolenanwendung. Wird eine Konsolenanwendung gestartet, erzeugt Windows ein Textfenster, mit dem der Anwender mit der Anwendung in Verbindung tritt.

Die Ein- und Ausgabe Standardtextdateien werden bei einer Konsolenanwendung dem Konsolenfenster automatisch zugeordnet.

Anmerkung

Die im System Unit deklarierte boolesche Variable IsConsole kann verwendet werden, um festzustellen, ob ein Programm als Konsolenanwendung oder unter einer grafischen Benutzeroberfläche läuft.

Hinweis:	Die $APPTYPE-Direktive ist nur in einem Programm sinnvoll. Sie sollte nicht in einer Bibliothek verwendet werden.


Vollständige Auswertung boolescher Ausdrücke {$B}, {$BOOLEVAL}
Auswertung boolescher Ausdrücke { $B }, { $BOOLEVAL }

Siehe auch	Compiler-Befehle

Dieser Schalter bewirkt die Festlegung auf eines der beiden Modelle, nach denen die Auswertung der booleschen Operatoren AND und OR durchgeführt wird.

Syntax:	{$B+} oder {$B-}

{$BOOLEVAL ON} oder {$BOOLEVAL OFF}

Voreinstellung:	{$B-}

{$BOOLEVAL OFF}

Gültigkeit:	Lokal

AN { $B+ }, {$BOOLEVAL ON}

Wenn diese Option eingeschaltet ist, erzeugt der Compiler Code für eine vollständige Auswertung eines booleschen Ausdrucks, der sich aus AND- und OR-Operatoren zusammensetzt, auch wenn das Ergebnis des Ausdrucks bereits bekannt ist.

AUS { $B- }, {$BOOLEVAL OFF}

Wenn diese Option ausgeschaltet ist, generiert der Compiler Code für die Auswertung nach dem sogenannten Kurzschlußverfahren (Short-Circuit).

Dies bedeutet, daß die Teile eines Ausdrucks in der Reihenfolge ihres Auftretens ausgewertet werden, und die Auswertung abbricht, sobald sich am Gesamtergebnis nichts mehr ändern kann.


Siehe auch

Boolesche Operatoren


Informationen zur Fehlersuche { $D }, { $DEBUGINFO }

Siehe auch	Compiler-Befehle

Dieser Schalter legt fest, ob der Compiler zusätzliche Informationen für den Debugger erzeugt oder nicht.

Syntax:	{$D+} oder {$D-}
{$DEBUGINFO ON} oder {$DEBUGINFO OFF}

Voreinstellung:	{$D+}
{$DEBUGINFO ON}

Gültigkeit:	Global

Anmerkungen:

Die Informationen für den Debugger bestehen aus einer Tabelle mit Zeilennummern für jede Routine, über die die Verbindung zwischen den Adressen der einzelnen Befehle und den Zeilen im Quelltext hergestellt werden kann.

Die Debug-Informationen vergrößern die Unit-Dateien und benötigen zusätzlichen Platz haben aber keinen Einfluß auf die Ausführungsgeschwindigkeit des Programms. Die Debug-Informationen werden zusammen mit dem Objektcode der Unit in einer .DCU-Datei gespeichert.

AN { $D+ }, { $DEBUGINFO ON }

Sind die Debug-Informationen eingeschaltet, wird die Debug-Information in die Unit-Datei (.DCU) geschrieben.

Sie können einen unabhängige oder einen integrierten Debugger verwenden, um den Quelltext schrittweise zu durchlaufen und Haltepunkte in Programmen zu setzen, die mit Debug-Information compiliert wurden. Falls ein Laufzeitfehler auftritt, kann der Compiler automatisch zu dem Ausdruck springen, der den Fehler verursachte.

Die Schaltfelder Projekt|Optionen|Linker Options|Map File erzeugen die komplette Zeileninformation nur, wenn Sie das Modul mit eingeschalteter Debug-Information compiliert haben.

Der Debug-Information-Befehl wird üblicherweise im Zusammenhang mit dem Befehl Local Symbols verwendet.

Falls Sie Ihr Programm mit dem Turbo Debugger für Windows überprüfen möchten, wählen Sie TDW Debugger-Info einbinden auf der Seite Linker der Dialogbox Optionen|Projekt und compilieren Sie Ihre Programm erneut.


Siehe auch

Debug- und Symbol-Information


Verwendung von Schalterbefehlen für Debug- und Symbolinformationen

Siehe auch	Compiler-Befehle

Die drei Compiler-Befehle $D, $L und $Y werden gemeinsam benutzt. $L und $Y können wie Untermengen von $D betrachtet werden, wobei $D den äußersten Gültigkeitsbereich hat, $L den nächstkleineren und $Y den innersten. Die folgende Tabelle beschreibt, wie diese Befehle sich gegenseitig beeinflussen, wenn sie gemeinsam benutzt werden:

Symbol	Ergebnis

{$D+, L-, Y+}	Erzeugung von Debug-Information für den Code des gesamten Abschnitts, keine Information bezüglich implementierter Symbole ($Y wird ignoriert).

{$D+, L-, Y-}	Erzeugung von Debug-Information für den Code des gesamten Abschnitts, keine Information bezüglich implementierter Symbole ($Y wird ignoriert).

{$D-, L+, Y+}	Überhaupt keine Information ($L, $Y wird ignoriert)

{$D+, L+, Y-}	Kein Symbolbezug oder andere ObjectBrowser-Information. Diese Einstellung kann beim Linken Zeit sparen.

{$D+, L+, Y+}	Erzeugung von Debug-Information über alle Symbole, die im Modul vorkommen: Zeilennummer, Symbolinformationen über lokale Variablen und Typen, Symbol-Querverweise und andere anzeigbare Information.


Siehe auch

$D Debug-Information

$L Lokale Symbolinformation

$Y Symbol-Referenz-Information


Automatische Überprüfung von Ein-/Ausgabe { $I }, { $IOCHECKS }

Siehe auch	Compiler-Befehle

Der Schalter zur automatischen Überprüfung der Ein-/Ausgabe legt fest, ob die Ergebnisse des Aufrufs einer Ein-/Ausgabe, wie z.B. Read, Write oder Erase, überprüft werden.

Syntax:	{$I+} oder {$I-}
{$IOCHECKS ON} oder {$IOCHECKS OFF}

Voreinstellung:	{$I+}
{$IOCHECKS ON}

Gültigkeit:	Lokal

AN { $I+ }, { $IOCHECKS ON }

Wenn die Ein-/Ausgabe-Überprüfung eingeschaltet ist, erzeugt der Compiler Code, um nach jedem Aufruf einer Ein-/Ausgabe-Routine auf Ein-/Ausgabefehler zu überprüfen. Im folgenden finden Sie das Ergebnis, wenn eine Überprüfung ein negatives Resultat liefert:

Sämtliche Laufzeitfehler stoppen Ihre Anwendung.

AUS { $I- }, { $IOCHECKS OFF }

Wenn die Ein-/Ausgabe-Überprüfung ausgeschaltet ist, müssen Sie die IOResult function verwenden, um Ein-/Ausgabefehler aufzufinden.


Siehe auch

$I Datei einfügen

Exception-Behandlung


Beschreibbare typisierte Konstanten { $J }, { $WRITEABLECONST }

Compiler-Befehle

Der Befehl $J regelt, welche typisierten Konstanten verändert werden können.

Syntax:	{$J+} or {$J-}
{$WRITEABLECONST ON} oder {$WRITEABLECONST OFF}

Voreinstellung:	{$J-}
{$WRITEABLECONST OFF}

Gültigkeit:	Local

An { $J+ }, { $WRITEABLECONST ON }

Im Modus {$J+} können typisierte Konstanten verändert werden und sind prinzipiell initialisierte Variablen.

Aus { $J- }, { $WRITEABLECONST OFF }

Im Modus {$J-}sind typisierte Konstanten wirklich konstant und jeder Versuch, sie zu verändern führt zu eriner Fehlermeldung des Compilers.


Lokale Symbolinformationen {$L}; {$LOCALSYMBOLS}
Lokale Symbolinformationen { $L }, { $LOCALSYMBOLS }

Siehe auch	Compiler-Befehle

Der $L-Befehl Schalter legt fest, ob der Compiler lokale Symbolinformationen erzeugen soll.

Syntax:	{$L+} oder {$L-}
{$LOCALSYMBOLS ON} oder {$LOCALSYMBOLS OFF}

Voreinstellung:	{$L+}
{$LOCALSYMBOLS ON}

Gültigkeit:	Global

Anmerkung

Die Informationen über lokale Symbole bestehen aus den Bezeichnern innerhalb der Prozeduren und Funktionen des Moduls. Die lokale Symbolinformation enthält keine globalen Variablen oder Namen, die im Schnittstellenabschnitt einer Unit deklariert werden.

Der Schalter für lokale Symbolinformation wird ignoriert, wenn der Schalter für die Debug-Information  ausgeschaltet ist.

AN { $L+ }, { $LOCALSYMBOLS ON }

Wenn der Schalter für die lokale Symbolinformation eingeschaltet ist, können Sie einen unabhängigen oder einen integrierten Debugger verwenden, um die lokalen Variablen zu untersuchen und zu ändern.

Wenn die Option Map-Datei auf der Seite Linker der Dialogbox Optionen|Projekt ausgewählt wird, wird lokale Symbolinformation für ein gegebenes Modul nur dann erzeugt, wenn das Modul mit $L+ compiliert wurde.

Die lokale Symbolinformation wird in die Unit-Datei aufgenommen, zusammen mit dem Objektcode der Unit. Lokale Symbolinformation vergrößert die Unit-Datei. Sie hat keinen Einfluß auf die Ausführungsgeschwindigkeit des Programms.

AUS { $L- }, { $LOCALSYMBOLS OFF }

Wird diese Option ausgeschaltet, so wird bei der Compilierung des Programms weniger Speicher benötigt, die Unit-Datei wird kleiner und der Umfang der Symbolinformationen des Debuggers nimmt ab.

Siehe auch

Debug- und Symbolinformation


Offene Parameter { $P }, { $OPENSTRINGS }

Siehe auch	Beispiel	Compiler-Befehle

Der $P-Befehl legt die Bedeutung variabler Parameter fest, die mit dem Schlüsselwort string deklariert wurden. Offene Parameter ermöglichen die Übergabe von String-Variablen unterschiedlicher Größe an dieselbe Prozedur oder Funktion.

Syntax:	{$P+} oder {$P-}
{$OPENSTRINGS ON} oder {$OPENSTRINGS OFF}

Voreinstellung:	{$P-}
{$OPENSTRINGS OFF}

Gültigkeit:	Global

AN { $P+ }, { $OPENSTRINGS ON }

Im Modus {$P+} sind String-Variablen (mit dem Schlüsselwort string deklariert) offene String-Parameter. Unabhängig vom Zustand dieses Schalters können offene String-Parameter jederzeit mittels OpenString deklariert werden.

Der aktuelle Parameter eines offenen String-Parameters kann eine Variable eines beliebigen String-Typs sein. Innerhalb einer Funktion oder Prozedur ist das Größenattribut (maximale Länge) des formalen Parameters gleich demjenigen des aktuellen Parameters.

Offene String-Parameter verhalten sich genauso wie variable Parameter eines String-Typs, mit der Ausnahme, daß sie nicht als reguläre variable Parameter an andere Prozeduren oder Funktionen übergeben werden können.

AUS { $P- }, { $OPENSTRINGS OFF }

Im Modus {$P-} werden keine offenen Parameter zugelassen. In diesem Modus sind variable Parameter, die mittels des Schlüsselwortes string deklariert wurden, normale variable Parameter. Dies dient vor allem der Kompatibilität mit früheren Versionen von Turbo Pascal.


Beispiel

procedure MyProc(var S:string);

   begin

     S:= 'abcdefghijk';

   end;

var

   shortstring: string[5];

     begin

       MyProc(ShortString);

     end.

Compiler-Schalter	Ergebnis

$P-, V+	MyProc(ShortString) erzeugt den Compiler-Fehler Typkonflikt.

$P+, V-	MyProc(ShortString) ist zugelassen und der erzeugte Code stellt sicher, daß Zuweisungen an S die deklarierte Größe des aktuellen Parameters nicht überschreiten. Nach dem Aufruf von MyProc ergibt sich ShortString zu 'abcde'.

$P-, V-	MyProc erzeugt keinen Compiler-Fehler, könnte aber einen Speicherüberschreibfehler in Ihrem Programm bewirken, der Ihr Programm zum Absturz bringen kann.


Siehe auch

$V Überprüfung von Var-Strings


Arithmetischer Überlauf { $Q }, { $OVERFLOWCHECKS }

Siehe auch	Compiler-Befehle

Dieser Compiler-Befehl steuert die Erzeugung von Code zur Prüfung von arithmetischen Bereichsüberläufen.

Syntax:	{$Q+} oder {$Q-}
{$OVERFLOWCHECKS ON} oder {$OVERFLOWCHECKS OFF}

Voreinstellung:	{$Q-}

Gültigkeit:	Lokal

Anmerkungen

Ein arithmetischer Überlauf tritt dann auf, wenn das Ergebnis einer Berechnung die Größe des Typs der Berechnung überschreitet. In einigen Fällen kann Infomation verlorengehen.

AN { $Q+ }, { $OVERFLOWCHECKS ON }

Im Modus $Q+ erzeugt der Compiler Code, um die folgenden Integer-Operationen auf Überlauf zu prüfen:

\	+	-	*	Abs	Sqr	Succ	Pred	Inc	Dec

Dem Programmcode, der für diese arithmetischen Operationen generiert wird, folgt zusätzlicher Code, der prüft, ob das Ergebnis innerhalb des zulässigen Bereichs liegt.

Falls ein Überlauf festgestellt wird, stoppt das Programm mit einem Laufzeitfehler.

Der Modus $Q+ setzt die Ausführungsgeschwindigkeit des Programms deutlich herab und vergrößert den Programmumfang. Sie sollten diesen Schalter ausschließlich in der Entwicklung- und Testphase Ihrer Programme aktivieren und ausschalten, wenn Sie Ihr endgültiges Produkt fertigstellen.

Der Modus $Q+ wird üblicherweise in Verbindung mit dem $R-Befehl eingesetzt.

AUS { $Q- }, { $OVERFLOWCHECKS OFF }

Wenn der Modus ausgeschaltet ist, wird kein Test auf arithmetischen Überlauf durchgeführt.


Siehe auch

Exception-Behandlung


Bereichsüberprüfung { $R }, { $RANGECHECKS }

Siehe auch	Compiler-Befehle

Dieser Schalter legt fest, ob der Compiler zusätzlichen Code zur Bereichsüberprüfung generiert.

Syntax:	{$R+} oder {$R-}
{$RANGECHECKS ON} oder {$RANGECHECKS OFF}

Voreinstellung:	{$R-}
{$RANGECHECKS OFF}

Gültigkeit:	Lokal

AN { $R+ }, { $RANGECHECKS ON }

Im Modus $R+ wird vom Compiler Code erzeugt, anhand dessen die Indizes von Arrays und Strings daraufhin überprüft werden, ob sie in den definierten Grenzen liegen, und daß alle Zuweisungen zu skalaren oder Unterbereichstypen im zulässigen Wertebereich liegen. Bereichsüberprüfung wird nicht für Inc und Dec durchgeführt.

Wird eine Bereichsverletzung festgestellt, stoppt das Programm mit einem Laufzeitfehler.

Der Modus $Q+ setzt die Ausführungsgeschwindigkeit des Programms deutlich herab und vergrößert den Programmumfang. Sie sollten diesen Schalter ausschließlich in der Entwicklung- und Testphase Ihrer Programme aktivieren und ausschalten, wenn Sie Ihr endgültiges Produkt fertigstellen.

AUS { $R- }, { $RANGECHECKS OFF }

Wenn die Bereichsüberprüfung ausgeschaltet ist, wird kein Code zur Bereichsüberprüfung erzeugt.


Siehe auch

$Q Arithmetischer Überlauf

Exception-Behandlung


Stack-Überprüfung { $S }, { $STACKCHECKS }

Compiler-Befehle

Dieser Schalter legt fest, ob der Compiler zusätzlichen Code zur Überprüfung von Stack-Überläufen erzeugt.

Syntax:	{$S+} oder {$S-}
{$STACKCHECKS ON} oder {$STACKCHECKS OFF}

Voreinstellung:	{$S+}
{$STACKCHECKS ON}

Gültigkeit:	Lokal

AN { $S+ }, { $STACKCHECKS ON }

Im Modus {$S+} wird vor jedem Prozedur- oder Funktionsaufruf geprüft, ob noch genügend Platz auf dem Stack zur Speicherung der Rücksprungadressen, der lokalen Variablen etc. vorhanden ist.

Hinweis:	Normalerweise sollte die Stack-Überprüfung immer (auch in der endgültigen Version des Programms) aktiviert sein, es sei denn, Sie sind sicher, daß Ihre Programm den Stack niemals zum Überlauf bringen wird.

AUS { $S- }, { $STACKCHECKS OFF }

Wenn der Modus $S ausgeschaltet ist und zu wenig freier Stack vorhanden ist, verursacht der  Aufruf einer Prozedur oder einer Funktion meistens einen Systemabsturz oder den Stopp des Programms mit einem Laufzeitfehler.


Getypter @-Operator {$T}, {$TYPEDADDRESS}
Getypter @ Operator { $T }, { $TYPEDADDRESS }

Siehe auch	Compiler-Befehle

Dieser Compiler-Befehl bestimmt den Typ des resultierenden Zeigers auf eine Variable, der durch die Anwendung des @-Operators auf eine variable Referenz erzeugt wurde.

Menübefehl:	Optionen|Projekt|Compileroptionen|Getyppter @ Operator

Syntax:	{$T+} oder {$T-}
{$TYPEDADDRESS ON} oder {$TYPEDADDRESS OFF}

Voreinstellung:	{$T-}
{$TYPEDADDRESS OFF}

Gültigkeit:	Lokal

AN { $T+ }, { $TYPEDADDRESS ON }

Im Modus {$T+} ist das Ergebnis des Operators ^T, wobei T der Typ der variablen Referenz ist. Zum Beispiel liefert die Anwendung des @-Operators auf eine Integer-Variable immer einen Pointer vom Typ Integer. Wird der @-Operator auf eine Prozedur, Funktion oder Methode angewendet, ist der resultierende Zeiger immer vom Typ Pointer, gleichgültig welcher Modus des Compiler-Befehls $T engestellt ist.

AUS { $T- }, { $TYPEDADDRESS OFF }

Im Modus {$T-} ist das Resultat des @-Operators immer ein ungetypter Zeiger (Pointer), gleich welchen Typs, der zu allen anderen Zeigern kompatibel ist.


Siehe auch

@-Operator


Pentium-sichere FDIV-Operationen { $U }, { $SAFEDIVIDE }

Compiler-Befehle

Der Befehl $U regelt die Generierung von Fließkommacode, der gegenüber der fehlerhaften FDIV-Anweisung früher Pentium-Prozessoren abgesichert ist.

Syntax:	{$U+} oder {$U-}
{$SAFEDIVIDE ON} oder {$SAFEDIVIDE OFF}

Voreinstellung:	{$U-}
{$SAFEDIVIDE OFF}

Gültigkeit:	Lokal

An { $U+ }, { $SAFEDIVIDE ON }

Im Modus {$U+} werden alle Fließkommadivisionen mittels einer Routine der Laufzeitbibliothek ausgeführt. Wenn diese Fließkommadivisionsroutine das erste Mal ausgeführt wird, prüft sie, ob die FDIV-Anweisung des Prozessors einwandfrei funktioniert und aktualisiert die Variable TestFDIV entsprechend (in der System-Unit deklariert). Bei allen folgenden Divisionen wird über die Variable TestFDIV entschieden, welche Routine verwendet wird.

Die folgende Tabelle enthält alle möglichen Werte für TestFDIV:

Wert	Bedeutung
-1	FDIV-Anweisung wurde geprüft und für fehlerhaft befunden.
0	FDIV-Anweisung wurde noch nicht geprüft.
1	FDIV-Anweisung würde geprüft und für fehlerfrei befunden.
Bei Prozessoren ohne FDIV-Fehler führt {$U+} nur zu geringfügigen Leistungseinbußen. Fehlerhafte Prozessoren benötigen im Modus {$U+} bis zu drei mal länger, liefern dafür allerdings immer das richtige Ergebnis..

Aus { $U- }, { $SAFEDIVIDE OFF }

Im Modus {$U-} werden Fließkommadivisionen mit den Inline-FDIV-Anweisungen durchgeführt. Dadurch ergibt sich eine optimale Geschwindigkeit und Codegröße, es kann jedoch zu Rechenfehlern bei fehlerhaften Pentium-Prozessoren kommen. Sie sollten {$U-} nur dann verwenden, wenn Sie sicher sein können, daß der Code niemals auf einem fehlerhaften Pentium-Prozessor ausgeführt wird.


Strenge Prüfung von Var-Strings {$V}, {$VARSTRINGCHECKS}
Prüfung von Var-Strings { $V }, { $VARSTRINGCHECKS }

Compiler-Befehle

Dieser Schalter legt fest, welche Prüfungen der Compiler bei der Übergabe von Short-Strings als VAR-Parameter vornimmt.

Syntax:	{$V+} oder {$V-}
{$VARSTRINGCHECKS ON} oder {$VARSTRINGCHECKS OFF}

Voreinstellung:	{$V+}
{$VARSTRINGCHECKS ON}

Gültigkeit:	Lokal

AN { $V+ }, { $VARSTRINGCHECKS ON }

Im Modus {$V+} vergleicht der Compiler den formalen String-Parameter vom Typ var mit dem aktuell übergebenen Parameter. Falls diese beiden nicht identisch sind, wird ein Compiler-Fehler ausgelöst.

AUS { $V- }, { $VARSTRINGCHECKS OFF }

Im Modus {$V-} kann jeder String-Typ als aktueller Parameter übergeben werden, auch wenn die deklarierte Länge nicht der des formalen Parameters entspricht.


Windows Stack Frame { $W }, { $STACKFRAMES }

Compiler-Befehle

Dieser Compiler-Befehl erzeugt speziellen Ein- und Ausgangscode für far-Prozeduren und -Funktionen für Programme, die im Windows 3.0 Real-Mode laufen.

Syntax:	{$W+} oder {$W-}
{$STACKFRAMES ON} oder {$STACKFRAMES OFF}

Voreinstellung:	{$W+}
{$STACKFRAMES ON}

Gültigkeit:	Lokal

AN { $W+ }, { $STACKFRAMES ON }

Im Modus $W+ erzeugt der Compiler spezielle Stack-Frames für Prozeduren und -Funktionen, auch wenn sie nicht genutzt werden.

Off { $W- }

Im Modus $W- erzeugt der Compiler Stack-Frames nur, wenn sie benötigt werden.

Bemerkung

Bei einigen Debuggern ist es nötig, daß Stack-Frames für alle Prozeduren und Funktionen erzeugt werden. Ist dies nicht der Fall, sollten Sie niemals den Zustand {$W+} verwenden.


Erweiterte Syntax {$X }, { $EXTENDEDSYNTAX }

Compiler-Befehle

Dieser Schalter legt fest, ob die erweiterte Syntax des Object Pascal-Compilers benutzt wird oder nicht.

Syntax:	{$X+} oder {$X-}
{$EXTENDEDSYNTAX ON} oder {$EXTENDEDSYNTAX OFF}

Voreinstellung:	{$X+}
{$EXTENDEDSYNTAX ON}

Gültigkeit:	Global

AN { $X+ }, { $EXTENDEDSYNTAX ON }

Im Modus {$X+} ist die Syntax von Object Pascal dahingehend erweitert, daß Sie benutzerdefinierte Funktionsaufrufe als Anweisungen (als wenn Sie Prozeduren wären) verwenden können.  Funktionen genauso wie Prozeduren aufgerufen werden, d.h. das Funktionsergebnis kann vernachlässigt werden. Die erweiterte Syntax erlaubt Ihnen außerdem die Verwendung von Null-terminierten Strings.

Funktionsaufrufe können als Anweisungen verwendet werden; das Ergebnis kann verworfen werden. Die erweiterte Syntax kann jedoch nicht auf Built-In-Funktionen (Funktionen, die in der Unit System definiert sind) angewandt werden. Die erweiterte Syntax ermöglicht außerdem die Unterstützung von Null-terminierten Strings, indem die speziellen Regeln, die auf den Built-In-Typ PChar und Null-basierte Arrays vom Typ Character angewandt werden, aktiviert werden.

AUS { $X- }, { $EXTENDEDSYNTAX OFF }

Im Modus {$X+} führen Versuche, die erweiterte Syntax zu verwenden, zu Compiler-Fehlern.


Symbolinformation { $Y } , { $REFERENCEINFO }

Siehe auch	Compiler-Befehle

Dieser Schalter legt fest, ob Informationen über Symbolreferenzen für Debug-Zwecke generiert werden.

Syntax:	{$Y+} oder {$Y-}
{$REFERENCEINFO ON} oder {$REFERENCEINFO OFF}

Voreinstellung:	{$Y+}
{$REFERENCEINFO ON}

Gültigkeit:	Global

Anmerkungen

Die Symbolreferenz-Information besteht aus Tabellen, in denen die Zeilennummern aller Deklarationen und Referenzen auf Symbole in einem Modul enthalten sind.

AN { $Y+ }, { $REFERENCEINFO ON }

Im Modus $Y+ kann der ObjectBrowser Informationen über Symboldefinitionen und Verweise aus dem Modul anzeigen, wenn ein Programm oder eine Unit compiliert wurde.

Symbolreferenz-Informationen für Units werden werden zusammen mit dem Objektcode der Unit in der entsprechenden .DCU-Datei gespeichert. Die Aufnahme dieser Informationen vergrößert den Umfang der Unit-Dateien, Größe und Ausführungsgeschwindigkeit des ausführbaren Programms werden jedoch nicht beeinträchtigt.

Der $Y-Schalter hat keine Wirkung, außer wenn die beiden Schalter $D und $L eingeschaltet sind.

AUS { $Y- }, { $REFERENCEINFO OFF }

Im Modus {$Y-} werden keine Symbolreferenz-Informationen generiert.


Siehe auch

Debug- und Symbolinformation


Include-Datei { $I Dateiname }, {$INCLUDE filename}
Include-Datei { $I Dateiname }, { $INCLUDE Dateiname }

Compiler-Befehle

Dieser Schalter weist den Compiler an, die angegebene Datei während des Compilierens einzulesen.

Syntax:	{$I Dateiname}
{$INCLUDE Dateiname}

Gültigkeit:	Lokal

Anmerkungen

Wenn die Angabe von DateiName keine Dateinamenserweiterung enthält, wird automatisch .PAS angenommen.

Wurde kein Verzeichnis angegeben, sucht der Object Pascal Compiler die Datei

zuerst im aktuellen Verzeichnis

und dann im Suchpfad.

Die Include-Datei wird in direktem Anschluß an den Befehl {$I DateiName} in den Quelltext eingebunden.

Hinweis:	Ein Include-Befehl darf nicht inmitten eines Anweisungsblockes stehen. Alle Anweisungen, die durch begin und end eingeschlossen sind, müssen sich in derselben Quelltextdatei befinden.


Objektdateien einbinden {$L Dateiname }, {$LINK filename}
Objektdateien einbinden {$L Dateiname }, { $LINK Dateiname }

Compiler-Befehle

Der Befehl weist den Linker an, die Datei DateiName in das Programm oder die Unit einzubinden.

Syntax:	{$L Dateiname}
{$LINK Dateiname}

Gültigkeit:	Lokal

Anmerkungen

Der $L-Befehl wird verwendet, um externe Routinen einzubinden, die anderen Programmiersprachen geschrieben und als external deklariert wurden.

Die angegebene Datei muß im relozierten Intel-Object-Format vorliegen (.OBJ-Datei).

Die Standardendung für Dateinamen ist .OBJ.

Wurde durch DateiName kein Verzeichnis angegeben, sucht der Object Pascal Compiler die Datei

zuerst im aktuellen Verzeichnis

und dann im Suchpfad.


Runtime Typinformation { $M }, { $TYPEINFO }

Compiler-Befehle

Regelt die Generierung von Runtime Typinformation.

Syntax:	{$M+} oder {$M-}
{$TYPEINFO ON} oder {$TYPEINFO OFF}

Voreinstellung:	{$M-}
{$TYPEINFO OFF}

Gültigkeit:	Lokal

Bemerkungen

Der Befehl $M egelt die Generierung von Runtime Typinformation. Wenn eine Klasse im Modus {$M+} deklariert oder von einer Klasse abgeleitet wird, die im Modus {$M+} deklariert wurde, erzeugt der Compiler Runtime Typinformation für Felder, Methoden und Eigenschaften, die ein einem Abschnitt deklariert wurden. Wird eine Klasse im Modus {$M-} deklariert und nicht von einer Klasse abgeleitet, die im Modus {$M+} deklariert wurde, sind die Abschnitte nicht zulässig.

Hinweis	Die Klasse Tpersistent, die in der visuellen Komponentenbibliothek (VCL) definiert wurde, wurde im Modus {$M+} deklariert, so daß jede von TPersistent abgeleitete Klasse veröffentlichte Abschnitte enthalten darf. VCL verwendet die Runtime Typinformation für veröffentlichte Abschnitte, um auf Werte der Eigenschaften der Komponenten zuzugreifen, wenn Formulardateien geladen oder gespeichert werden.Weiterhin verwendet die IDE die Runtime-Typinformation von Komponenten, um die Liste der Eigenschaften im Object Inspector aufzustellen.

Es gibt für eine Anwendung nur selten, wenn überhaupt nicht, die Notwendigkeit, den Compilerschalter $M zu setzen.


Speicherbelegung {$M Größen }, {$MAXSTACKSIZE }, { $MINSTACKSIZE }

Compiler-Befehle

Legt die Parameter für die Allokation des Programmstapelspeichers fest.

Syntax:	{$M minstackgröße, maxstackgröße}
{$MINSTACKSIZE Zahl}
{$MAXSTACKSIZE Zahl}

Voreinstellung:	{$M 16384, 1048576}

Gültigkeit:	Global

Anmerkungen

Der Schalter $M gibt die Stackspeicherbelegung einer Anwendung an. Minstacksize muß eine Ganzzahl zwischen 1024 und 2147483647 sein, die die Minimalgröße des Stacks einer Anwendung angibt. Maxstacksize muß eine Ganzzahl zwischen Minstacksize und 2147483647 sein, und gibt die Maximalgröße des Anwendungsstacks an.

Wenn nicht genug Speicher verfügbar ist, um die Minimalanforderungen zu erfüllen, meldet Windows einen Fehler beim Versuch, die Anwendung zu starten.

Der Stack der Anwendung darf niemals größer als die maximale Stackgröße werden. Jeder Versuch, den Stack über diesen Wert hinaus zu vergrößern, führt zu einer EstackOverflow-Exception.

Die Befehle $MINSTACKSIZE und $MAXSTACKSIZE ermöglichen die getrennte Festlegung der minimalen und maximalen Stackgröße.

Hinweis	Die Anweisungen zur Speicherbelegung sind nur für ein Programm sinnvoll. Sie sollten nicht in einer Bibliothek oder einer Unit verwendet werden.


Modulbeschreibung { $D Text } , { $DESCRIPTION Text }

Compiler-Befehle

Fügt den angegebenen Text in den Modulbeschreibungseintrag im Header einer EXE- oder DLL-Datei ein.

Syntax:	{$D text}
{$DESCRIPTION Text}

Scope:	Global

Bemerkungen

Nur eine Modulbeschreibung kann in einem Programm- oder einer DLL-Quelldatei auftauchen. Verwenden Sie $D nicht in Unit-Quelldateien.


Ressourcendatei { $R Dateiname}, {$RESOURCE Dateiame}
Ressourcendatei { $R Dateiname}, { $RESOURCE Dateiname }

Compiler-Befehle

Benennt die Ressourcendatei, die in ein Programm oder in eine Bibliothek aufgenommen werden soll.

Syntax:	{$R Dateiame}
{$RESOURCE Dateiname}

Gültigkeit:	Lokal

Anmerkungen

Die Vorgabeendung für DateiName ist .RES. Es muß sich hierbei um eine Windows-Ressourcendatei handeln.

Wird in DateiName kein Verzeichnis angegeben, sucht der Compiler die Datei

zuerst im aktuellen Verzeichnis,

dann im Suchpfad.

Beim Verwenden in einer Unit wird die Ressourcen-Datei einfach in die Unit-Datei aufgenommen. Es wird dabei nicht geprüft, ob die Datei zur Compilierzeit existiert.

Beim Linken eines Programms oder einer Bibliothek werden die Ressourcendateien aller Units und des Programms bearbeitet, und jede Ressource jeder Ressourcendatei wird in die erzeugte .EXE oder .DLL-Datei kopiert.

Hinweis:	Dieser Befehl erlaubt mehrere .RES-Dateien pro Unit. Es gibt während der Compilierung keine Bestätigung des Inhalts oder der Gültigkeit einer .RES-Datei (ob sie existiert). Dateien, die mit dem $R-Befehl angegeben werden, müssen während des Linkvorgangs  präsent sein, oder Sie erhalten die Fehlermeldung „File not found (<DateiName>.RES)".


Wortgröße von Aufzählungstypen { $Z }, { $MINENUMSIZE }

Compiler-Befehle

Dieser Compiler-Befehl legt die minimale Größe vonAufzählungstypen fest.

Syntax:	{$Z1} oder {$Z2} oder {$Z4}
{$MINENUMSIZE 1} oder {$MINENUMSIZE 2} oder {$MINENUMSIZE 4}

Voreinstellung:	{$Z1}
{$MINENUMSIZE 4}

Gültigkeit:	Lokal

Bemerkungen

Ein Aufzählungstyp wird als vorzeichenloses Byte gespeichert, wenn die Aufzählung nicht mehr als 256 Werte besitzt und wenn der Typ im Modus {$Z1} deklariert wurde (die Voreinstellung). Wenn ein Aufzählungstyp mehr als 256 Werte besitzt, oder wenn der Typ im Modus {$Z2} deklariert wurde, wird er als vorzeichenloses Wort gespeichert. Wird ein Aufzählungstyp im Modus {$Z4} deklariert, wird er als vorzeichenloses Langwort gespeichert.

Die Modi {$Z2} und {$Z4} sind sinnvoll, wenn Schnittstellen zu C- und C++-Bibliotheken bestehen, in denen Aufzählungstypen normalerweise als Wort oder Langwort dargestellt werden.


Warnungen { $WARNINGS }

Siehe auch	CompilerBefehle

Dieser Compilerbefehl regelt die Erstellung von Warnmeldungen.

Syntax:	{$WARNINGS ON} oder {$WARNINGS OFF}

Voreinstellung:	{$WARNINGS OFF}

Gültigkeit:	Lokal

An { $WARNINGS ON }

Wenn die Warnungen eingeschaltet sind, gibt der Compiler im Nachrichtenfenster aus, wenn er auf uninitialisierte Variablen, fehlende Funktionsergebnisse, konstrukte abstrakter Objekte usw. trifft.

Aus { $WARNINGS OFF }

Mit dieser Einstellung gibt der Compiler keine Warnmeldungen aus.


Siehe auch

Hinweise


Hinweise { $HINTS }

Siehe auch	Beispiel	Compiler-Befehle

Der Befehl $HINTS legt fest, ob der Compiler beim Compilieren Hinweismeldungen ausgibt.

Syntax:	{$HINTS ON} oder {$HINTS OFF}

Voreinstellung:	{$HINTS OFF}

Gültigkeit:	Local

An { $HINTS ON }

Bei eingeschalteten Hinweisen gibt der Compiler Hinwiesmeldungen im Meldungsfenster aus, wenn er nicht verwendete Variablen, nicht verwendete Zuweisungen, for oder while-Schleifen, die niemals ausgeführt werden entdeckt, usw.

Aus { $HINTS OFF }

Der Compiler gibt keine Hinweismeldungen aus.

Bemerkungen

Durch das Plazieren den Befehle {$HINTS OFF} und {$HINTS ON} im Code, können Sie die Hinweismeldungen für bestimmte Codeabschnitte aktivieren bzw. deaktivieren.


Beispiel

{ Das folgende Beispiel zeigt, wie der Compiler angewiesen wird, keine Hinweise über unbenutzte Variablen auszugeben. }

{$HINTS OFF}

procedure Test;

var

  I: Integer;

begin

end;

{$HINTS ON}


Siehe auch

Warnungen


Code-Image Base Adresse {$IMAGEBASE}
Code-Image Base { $IMAGEBASE Adresse }

Compiler-Befehle

Der Befehl $IMAGEBASE legt die vorgegebene Ladeadresse einer Anwendung oder einer DLL fest.

Syntax:	{$IMAGEBASE Zahl}

Voreinstellung:	{$IMAGEBASE $00400000}

Gültigkeit:	Global

Bemerkungen

Das Argument Zahl muß eine 32-Bit-Ganzzahl sein, die die Basisadresse angibt.Die Zahl muß größer oder gleich $00010000 sein und die unteren 16 Bit des Arguments werden ignoriert und sollte auf Null stehen.

Wird ein Modul (Anwendung oder DLL) in den Adreßraum eines Prozesses geladen, versucht Windows, das Modul an seine vorgegebene Basisadresse zu laden. Funktioniert dies nicht, wenn also der vorgegebene Adreßraum bereits reserviert ist, wird das Modul an eine von Windows bestimmte Adresse reloziert.

Es gibt nur selten oder nie einen Grund, die Image-Basisadresse einer Anwendung zu verändern. Für DLLs wird jedoch empfohlen, den Befehl $IMAGEBASE zu verwenden, um einen nicht vorgegebene Basisadresse zu wählen, da die vorgegebene Adresse $00400000 mit hoher Wahrscheinlichkeit nicht zur Verfügung stehen wird. Der für DLLs empfohlene vorgegebene Adreßbereich reicht von $40000000 bis $7FFFFFFF. Adressen in diesem Bereich sind für Prozesse unter Windows NT und Windows 95 immer verfügbar.

Wenn Windows eine DLL an die Basisadresse laden kann, ist die Ladezeit verringert, da keine Relozierung erfolgen muß. Wenn der angegebene Adreßbereich weiter für mehrere Prozesse verfügbar ist, können Codebestandteile der DLL unter diesen Prozessen gemeinsam verwendet und damit Ladezeiten und Speicherbedarf verringert werden.


Lange Strings { $H }, { $LONGSTRINGS }

Siehe auch	Compiler-Befehle

Der Befehl $H legt die Bedeutung des reservierten Wortes string bei alleiniger Verwendung in einer Typdeklaration fest.

Syntax:	{$H+} oder {$H-}
{$LONGSTRINGS ON} oder {$LONGSTRINGS OFF}

Voreinstellung:	{$H+}
{$LONGSTRINGS ON}

Gültigkeit:	Global

Bemerkungen

Der generische Typ string kann entweder einen langen, dynamisch zugewiesenen String (der grundlegende ANSI-String) oder einen kurzen, statisch zugewiesenen String bezeichnen.

An { $H+ }, { $LONGSTRINGS ON }

Bei der Vorgabe {$H+} definiert der Object Pascal Compiler den generischen Typ String als langen Ansi String. Alle Komponenten der Visuellen Komponentenbibliothek (VCL) werden in diesem Modus compiliert. Wenn Sie Kompoenenten schreiben, sollten diese ebenfalls lange Strings verwenden. Dies sollten alle Codesegmente machen, die Daten von VCL String-Eigenschaften übernehmen.

Aus { $H- }, { $LONGSTRINGS OFF }

Der Modus {$H-} ist dann am nützlichsten, wenn Code aus Versionen von Object Pascal verwendetm das auf kurze Strings voreingestellt ist. Sie können die lokale Bedeutung von Stringdefinitionen übergehen, um sicherzustellen, daß kurze Strings generiert werden. Sie können außerdem die Deklarationen kurzer Strings mittels string[255] oder ShortString vornehmen, die unabhängig von der $H-Einstellung sind.


Siehe auch

Lange Zeichenkettenarten

Kurze Zeichenkettenarten


Optimierung { $O }, { $OPTIMIZATION}

Compiler-Befehle

Syntax:	{$O+} oder {$O-}
{$OPTIMIZATION ON} oder {$OPTIMIZATION OFF}

Voreinstellung:	{$O+}
{$OPTIMIZATION ON}

Gültigkeit:	Lokal

Der Befehl $O steuert die Codeoptimierung. Im Modus {$O+} nimmt der Compiler eine Reihe von Codeoptimierungen vor, wie z.B. das Plazieren von Variablen in CPU-Registern, das Entfernen allgeimeiner Unterausdrücke und die Generierung induzierter Variablen. Im Modus {$O-} sind all diese Optimierungen ausgeschaltet.

Im Gegensatz zu bestimmten Situationen bei der Fehlersuche sollten Sie die Optimierung niemals ausschalten. Alle vom Object Pascal Compiler ausgeführten Optimierungen haben garantiert keinen Einfluß auf das Programm. Es werden also keine unsicheren Optimierungen vorgenommen, die der Programmierer genau prüfen muß.


Sprachdefinition

Sprachreferenzen

Die unten aufgelisteten Themenbereiche sind die Elemente der formalen Sprachdefinition von Object Pascal.

Einige dieser Themenbereiche verwenden Syntaxdiagramme, um Aspekte von Object Pascal zu verdeutlichen. Wenn Sie mit Syntaxdiagrammen nicht vertraut sind, so können Sie in Wie man Syntaxdiagramme liest nachschlagen.

Sie können diese Seiten aus dem Hilfe-Inhalt heraus, aus der Hilfe-Suche heraus oder direkt vom Code-Editor aus (mit STRG+F1), aufrufen.

Anweisungen

Arrays

Ausdrücke

Ausnahmebehandlung

Bezeichner

Blöcke

Compiler-Direktiven

DLLs

Funktionen

Geltungsbereich

Konstantendeklarationen

Kommentare

Labels

Methoden

Operatoren

Prozeduren

Reservierte Wörter

Schleifen

Spezielle Symbole

Strings

Tokens

Typdeklarationen

Typisierte Konstanten

Units

Variablen

Zahlen

Zeichenketten


Sprachreferenz

Sprachdefinition

Sie können diese Seiten aus dem Hilfe-Inhalt heraus, aus der Hilfe -Suche heraus oder direkt vom Code-Editor aus (mit STRG+F1), aufrufen.

Compiler-Direktiven

Bedingte Direktiven und Symbole

Reservierte Wörter

Standard-Direktiven


Wie man ein Syntax-Diagramm liest

Das Lesen von Syntax-Diagrammen ist eine Grundvoraussetzung für das Erlernen der Programmiersprache Object Pascal. Auch dieses Hilfe-System enthält Syntax-Diagramme. Diese enthalten die vordefinierte Folge der syntaktischen Elemente des jeweiligen Bestandteils der Programmiersprache.

Um ein Syntax-Diagramm zu lesen, folgen Sie den Pfeilen. Gelegentlich sind mehrere Wege möglich und legal.

Tatsächliche Bestandteile in Ihrem Code sind in dem Diagramm fett dargestellt.

Die Umrahmungen in einem Syntax-Diagramm repräsentieren spezielle syntaktische Elemente. Dies sind:

Rahmen	Bedeutung

Viereck	Konstrukte

Kreis	reservierte Wörter, Operatoren und Interpunktion


Blöcke

Siehe auch

Ein Block besteht aus Anweisungen.

Blocks sind Teil der Prozedurdeklaration, Funktionsdeklaration, Methodendeklaration oder eines Programms oder einer Unit.

Deklarationsteil

Ein Deklarationsteil kann folgende Elemente enthalten:

Labels

Konstanten

Typdeklarationen

Variablen

Prozeduren

Funktionen

Export Anweisungen

Alle Bezeichner und Label, die Sie in einem Block deklarieren haben den Gültigkeitsbereich lokal zu diesem Block.

Anweisungsteil

Der Anweisungsteil eines Blocks ist eine zusammengesetzte Anweisung. Dies bedeutet, daß er aus einer oder mehreren Anweisungen besteht und in begin und end eingeschlossen ist.


Siehe auch

Begin..end

Gültigkeitsbereich Block

Anweisungen


Konstantendeklarationen
Konstanendeklarationen

Siehe auch

Eine Konstante ist ein Bezeichner,der einen Wert repräsentiert, der sich nicht ändern kann. Der Geltungsbereich der Konstanten ist nur der die Deklaration umschließende Block. Ein Bezeichner einer Konstanten kann nicht für seine eigene Deklaration verwendet werden.

Konstanten werden mit dem reservierten Wort const deklariert.

In Object Pascal ist die Verwendung von konstanten Ausdrücken möglich, die vom Compiler ausgewertet werden, ohne daß das Programm tatsächlich ausgeführt wird.

Da Object Pascalum Zeitpunkt des kompilierens einen konstanten Ausdruck vollständig auswerten muß, sind die folgenden Konstruktionen in kostanten Ausdrücken nicht erlaubt.

Referenz auf Variablen und typisierte Konstanten (außer bei konstanten Adreß-Ausdrücken).

Der @ operator (außer in konstanten Adreß-Ausdrücken)

Funktionsaufrufe (außer bei folgendem)

Abs	Odd

Addr	Ord

Chr	Pred

Hi	Round

High	SizeOf

Length	Succ

Lo	Swap

Low	Trunc

Die folgenden binärarithmetischen und booleschen Operatoren können in konstanten Ausdrücken ebenfalls verwendet werden:

+	shr

-	shl

/	and

div	or

mod	xor

=


Siehe auch

Gültigkeitsbereich

Typisierte Konstanten


Variablen

Siehe auch	Beispiel

Eine Variable ist ein Bezeichner, der einen Wert repräsentiert, der sich ändern kann. Sie können diese im Variablendeklarationsteil einer unit, procedure, function, oder eines Programmms deklarieren.

In einer Variablendeklaration müssen Sie einen Bezeichner und den zugehörigen Typ deklarieren.

Der Typ einer Variablen kann ein vorher deklarierter Typbezeichner in den folgenden vorausgehen:

in einer type-Deklaration im gleichen Block oder

in einem umschließenden Block oder

in einer Unit.

Variablen können auch neue Typen deklarieren.

Der Geltungsbereich eines Variablen-Bezeichners ist der die Deklaration umschließende Block. Die Variable kann in diesem Block referenziert werden, es sei denn in einem eingeschlossenen Block ist dieser Bezeichner redeklariert.

Eine Redeklaration erzeugt eine neue Variable, die den selben Bezeichner verwendet, ohne daß der Wert der eigentlichen Variablen beeinträchtigt wird.


Siehe auch

Globale und lokale Variablen

Gülzigkeitsbereich

Unit

Var (reserviertes Wort)

Variablen Referenz

Variablen Typumwandlung

Initialisierte Variablen


Beispiel

var

  X, Y, Z: Real;

  I, J, K: Integer;

  Digit: 0..9;

  C: Color;

  Done,Error: Boolean;

  Operator: (Plus, Minus, Times);

  Hue1, Hue2: set of Color;

  Today: Date;

  Matrix: array[1..10, 1..10] of Real;


Globale und lokale Variablen

Siehe auch 	Variablen

Globale Variablen werden außerhalb von Prozeduren und Funktionen deklariert. Globale Variablen sind zugreifbar für alle

Prozeduren

Funktionen

Methoden

Lokale Variablen werden innerhalb von Prozeduren und Funktionen deklariert. Sie sind nur im umschließenden Block zugreifbar und werden bei Verlassen der Prozedur oder Funktion gelöscht.

Lokale Variablen und Stack

Variablen, die innerhalb von Prozeduren und Funktionen deklariert werden, heißen lokale Variablen und werden im Stack einer Anwendung abgelegt. Bei jedem Funktionsaufruf weist eine Prozedur eine Reihe lokaler Variablen auf dem Stack zu. Beim Verlassen werden die lokalen Variablen gelöscht.

Der Stack einer Anwendung wird von zwei Werten definiert: der minimalen und der maxiamlen Stack-Größe. Die Werte werden mit Hilfe der Compiler-Direktiven $MINSTACKSIZE und $MAXSTACKSIZE gesteuert und standardmäßig auf 16.384 (16K) und 1.048.576 (1M) festgelegt. Einer Anwnedung steht jederzeit die minimale Stack-Größe zur Verfügung. Gleichzeitig kann der Stack einer Anwendung niemals die maximale Stack-Größe übersteigen.

Steht nicht genügend Speicher für den Mindestbedarf an Stack einer Anwendung zur Verfügung, so meldet Windows einen Fehler, wenn versucht wird, diese Anwendung zu starten.

Benötigt eine Anwendung mehr Stack, als für die minimale Stack-Größe angegeben, so wird je nacj Bedarf zusätzlicher Speicher in Schritten zu je 4K zugewiesen. Schlägt die Zuweisung von weiterem Stack-Speicher fehl, zum Beispiel weil kein Speicher mehr zur Verfügung steht oder weil der Stack die maximale Stack-Größe übersteigen würde, so wird der Fehler EStackOverflow ausgelöst.


Siehe auch

Gültigkeitsbereich


Initialisierte Variablen

Siehe auch	Variablen

Wird durch eine Variablendeklaration eine einzelne globale Variable deklariert, so kann dabei wahlweise ein Anfangswert für die Variable angegeben werden. Wird bei der Deklaration einer globalen Variable nicht ausdrücklich ein Anfangswert angegeben, so wird der von der Variable belegte Speicher anfangs auf Null gesetzt.

Es ist nicht möglich, einen Anfangswert für eine lokale Variable anzugeben, und bei Beginn einer Prozedur oder Funktion besitzen alle lokalen Variablen unbestimmte Werte.


Siehe auch

Typisierte Konstanten

Globale und lokale Variablen


Variablen Referenzen

Siehe auch

Eine Variablen-Referenz bezeichnet:

Eine Variable

Eine Komponente einer Variablen mit strukturiertem oder String-Typ.

Eine dynamische Variable auf die eine zeiger-typ Variable verweist.

Die Struktur einer Variablen-Referenz ist folgendermaßen:

Die Syntax einer Variablen-Referenz lässt einen Ausdruck zu, der einen Zeigerwert berechnet. Der Ausdruck muß von einem Qualifizierer gefolgt werden, der den Zeigerwert dereferenziert ( möglich ist auch eine Indizierung, wenn die erweiterte Syntax mit der Direktive {$X+} zugelassen ist.), um eine tatsächliche Variablen-Referenz zu erhalten.


Siehe auch

Zeigertyp Variablen

Qualifizierer

String-Typ Variablen

Variablen strukturierten Typs

Variablen

Variablen Typumwandlung


Qualifizierer

Siehe auch 	Variablen Referenzen

Qualifizierer verändern die Bedeutung einer Variablen-Referenz. Eine Variable kann weder mehrere noch keine Referenz haben.

Ein Array-Bezeichner, der das ganze Array referenziert, hat keinen Qualifizierer.

Ein Array-Bezeichner gefolgt von einem Index repräsentiert eine spezifische Komponente des Arrays.

Mit einer Record oder object Komponente können Sie dem Index mit einem Feldkennzeichner folgen, der entweder ein spezielles Feld oder eine spezielle Array-Komponente repräsentiert.

Sie können dem Feldbezeichner in einem Zeigerfeld mit dem Zeigersymbol (^) folgen, um zwischen dem Zeigerfeld und der dynamischen Variablen, auf die es zeigt zu unterscheiden.

Wenn die Variable, auf die gezeigt wird, ein Array ist, können Sie Indizes hinzufügen, um die Komponenten des Arrays zu bezeichnen.

Das Zeigersymbol ist optional, wenn ein strukturierter Typ dereferenziert wird.


Siehe auch

Array-Typen

Feld- und Objektbestandteil-Kennzeichner

Indizes

Zeiger und dynamische Variablen

Zeigertypen

Variablen Referenzen


Indizes

Siehe auch 	Variablen Referenzen

Indizes ermöglichen den Zugriff auf ein spezielles Array-Element, String-Element oder String-Listen-Element.

Array Indizes

Der Index eines Arrays ermöglicht den Zugriff auf eine spezielle Komponente eines Arrays.

Der Indexausdruck wählt die Komponenten in der jeweils entsprechenden Dimension des Arrays aus. Für Array-Indizes gibt es folgende Einschränkungen:

Die Anzahl der Ausdrücke kann die Anzahl der Indextypen in der Array-Deklaration nicht überschreiten.

Der Typ jedes Ausdrucks muß zuweisungskompatibel zum entsprechenden Indextyp sein.

String-Indizes

Sie können eine kurze String-Variable mit einen einzelnen Indexausdruck indizieren, deren Wert zwischen 0 und N liegen muß (N ist die deklarierte maximale Länge des kurzen Strings). Der Typ eines Zeichens, auf das durch die Indizierung eines kurzen Strings zugegriffen wird, ist Char. Der Index des ersten Zeichens in einem String ist 1. Das Element bei Index 0 enthält die dynamische Länge des Strings.

Man kann eine nicht leere lange String-Variable mit einem einzelnen Indexausdruck indizieren, deren Wert 1 und N liegen muß. (N ist die dynamische Länge des langen Strings). Der Typ eines Zeichens, auf das durch die Indizierung eines langen Strings zugegriffen wird, ist Char. Der Index des ersten Zeichens in einem langen String ist 1.

Ein Wert vom Typ PChar, PAnsiChar oder PWideChar kann mit einem einzelnen Indexausdruck vom Typ Integer indiziert werden. Der Indexausdruck bestimmt einen Offset (Anzahl der Zeichen oder breite Zeichen), der dem Zeichenzeiger hinzugefügt wird, ehe er zu einer Variablenreferenz vom Typ Char, AnsiChar oder WideChar dereferenziert wird.

Um die Länge eines Strings festzustellen,

verwenden Sie die Funktion Length.

String-Listen-Indizes

Der Index einer String-Liste ermöglicht den Zugriff auf einen String innerhalb der Liste.

Die String-Liste hat eine indizierte Eigenschaft Strings,, die Sie wie ein Array aus Strings behandeln können.

Da die Eigenschaft Strings den normalen Zugriff auf eine String-Liste darstellt, ist Strings die Standardeinstellung. Das bedeutet, daß Sie den String-Bezeichner auslassen können und die String-Liste als Array aus Strings behandeln können.

Um auf einen String aus der Liste zuzugreifen, referenzieren Sie diesen mit seinem Index. Die Zählung des Indexes beginnt mit Null, so daß eine Liste aus drei Strings die Indexwerte 0, 1 und 2 verwendet.

Um den höchsten Indexwert festzustellen, verwenden Sie die Eigenschaft Count. Wenn Sie versuchen auf einen Indexwert außerhalb des gültigen Indexbereiches zuzugreifen, so wird eine Ausnahmebehandlung aufgerufen.


Siehe auch

Array-Typen

Qualifizierer

String-Typen


Beispiel

In diesem Beispiel wird auf eine Zelle eines Arrays zugegriffen.

Matrix[I, J];

Die beiden folgenden Beispiele haben die selbe Auswirkung, nämlich die erste Zeile in einem Memo-Feld zu setzen.

Memo1.Lines.Strings[0] := 'Dies ist dierste Zeile.';

Memo1.Lines[0] := 'Dies ist die erste Zeile.';


Feld- und Objekt-Kennzeichner
Feld- und Objektkennzeichner

Siehe auch	Beispiel 	Variablen Referenzen

Feldkennzeichner

Ein Feldkennzeichner ermöglicht den Zugriff auf ein bestimmtes Feld eines Record.

In einer Anweisung innerhalb einer with-Anweisung muß einem Feldkennzeichner nicht die Variablen-Referenz des enthaltenden Record vorangestellt werden.

Objekt-Komponenten-Kennzeichner

Der Objekt-Komponenten-Kennzeichner ermöglicht den Zugriff auf eine bestimmte Komponente eines Objektes. Ein Objektkennzeichner, der eine Methode kennzeichnet wird Methodenkennzeichner genannt.

Die Instanz und der Punkt können in folgenden Fällen entfallen:

bei referenzierenden Komponenten, die die with-Anweisng verwenden.

In einem Methodenblock, da die Wirkung die gleiche wie beim Schreiben von Self ist.


Siehe auch

Klassentypen

Record-Typen

With-Anweisung


Beispiel

Beispiele für den Zugriff auf Felder eines Record:

Today.Year

Results[1].Count

Results[1].When.Month


Zeiger und dynamische Variablen

Siehe auch	Beispiel

Zeigervariablen enthalten den Wert nil oder die Adresse einer dynamischen Variablen.

Die dynamische Variable, auf die von einer Zeigervariablen gezeigt wird, wird durch Schreiben des Zeigersymbols (^) vor der Zeigervariable referenziert.

Sie können dynamische Variablen und deren Zeigerwerte mit den Prozeduren New oder GetMem erzeugen.

Sie können den Operator @ (address-of) und die Funktion Addr verwenden, um Zeigerwerte zu erzeugen, die als Zeiger auf dynamische Variablen benutzt werden.

Nil zeigt nicht auf eine Variable. Das Ergebnis des Zugriffs auf eine dynamische Variable deren Zeigerwert nil oder undefiniert ist, ist undefiniert.


Siehe auch

Zeigertypen

Variablen


Beispiel

Die folgenden Beispiele sind Referenzen auf dynamische Variablen.

Pl^

Pl^.Siblings^

Results[1].Data^


Variablen-Typumwandlung

Siehe auch	Beispiel 	Variablen

Die Variablen-Typumwandlung ändert den Typ einer Variablen-Referenz in einen anderen Typ.

Wenn eine Variablen-Typumwandlung auf eine Variablen-Referenz angewendet wird, so wird die Variablen-Referenz als Instanz des Typs, der durch den Typ-Bezeichner angegeben wird, behandelt. Die Größe der Variablen muß mit der Größe des beabsichtigten Typs übereinstimmen. Wenn mit Hilfe des Operators as operator, die Zulässigkeit der Umwandlung geprüft wird und eine Ausnahme auftritt, ist die Variable nicht zuweisungskompatibel zu dem zugewiesenen Typen. Wenn die Typumandlung mittels des Namens des Typs gefolgt von der eingeklammerten Variable durchgeführt wird, erfolgt keine Prüfung.

Eine Variablen-Typumwandlung kann je nach Typ von einem oder mehreren Qualifizierern gefolgt werden.

Object Pascal untrestützt Variablen-Typumwandlungen mit prozeduralen Typen.


Siehe auch

Qualifizierer

Wert Typumwandlungen


Beispiel

Ausgehend von den folgenden Deklarationen

type

  Func = function(X: Integer): Integer;

var

  F: Func;

  P: Pointer;

  N: Integer;

können Sie die folgenden Zuweisungen verwenden:

F := Func(P);     { weist procedurealen Wert in P nach F zu }

  Func(P) := F;     { weist proceduralen Wert in F nach P zu }

  @F := P;          { weist Zeigerwert in P nach F }

  P := @F;          { weist Zeigerwert in P nachto F }

  N := F(N);        { ruft Funktion über F auf }

  N := Func(P)(N);  { ruft Funktion über P auf }


Bezeichner

Beispiel	Sprachdefinition

Bezeichner sind beschreibende Namen, die Sie jedem Element eines Object Pascal-Programms geben.

Konstanten

Felder in Records

Funktionen

Labels

Prozeduren

Programme

Typen

Units

Variablen

Bezeichner unterscheiden nicht in Groß- und Kleinschreibung.

Für die Namengebung gibt es folgende Beschränkungen:

Bezeichner können eine beliebige Länge haben, signifikant sind aber nur die ersten 63 Zeichen.

Das erste Zeichen eines Bezeichners muß ein Buchstabe oder der Unterstrich (_) sein.

Die übrigen Zeichen müssen Buchstaben, Zahlen oder Unterstriche sein.

Leerzeichen sind innerhalb von Bezeichnern nicht zugelassen.

Qualifizierte Bezeichner

Qualifizierte Bezeichner sind nützlich, um Namenskonflikte zu vermeiden, wenn mehrere Instanzen des gleichen Bezeichners existieren. Sie können einen Bezeichner mit einem anderen Bezeichner qualifizieren, um eine spezielle Instanz auszuwählen.


Beispiel

Normale Bezeichner sind zum Beispiel:

TextFile

Exit

Real2String

Qualifizierte Bezeichner sind zum Beispiel:

System.MemAvail  (* unit = System, identifier = MemAvail *)

System.CloseFile;


Typisierte Konstanten

Siehe auch	Beispiel

Die Deklaration einer typisierten Konstante entspricht der Deklaration einer Nur-Lesen-Variablen. Typisierte Konstanten können genau wie Variablen desselben Typs verwendet werden, nur können Sie nicht verändert werden.

Zusätzlich zu den Eigenschaften einer normalen Konstanten, kann der Wert einer typisierten Konstanten mit einem konstanten Adreßausdruck spezifiziert werden.

Es gibt fünf Kategorien typisierter Konstanten:

Zeigertyp Konstanten

Konstanten prozeduralen Typs

Konstanten einfachen Typs

String-Typ-Konstanten

Konstanten strukturierten Typs

Hinweis	Die Compiler-Direktive $J ermöglicht die Deklaration von typisierten Konstanten, die geändert werden können. Typisierte Konstanten, die im Standardzustand {$J-} deklariert werden, können nur gelesen und nicht verändert werden.


Siehe auch

Konstantendeklaration

Initialisierte Variablen


Beispiel

(* Typisierte Konstanten Deklaration *)

type

  Point = record X, Y: real end;

const

  Minimum: Integer = 0;

  Maximum: Integer = 9999;

  Factorial: array[1..7] of Integer = (1, 2, 6, 24, 120, 720, 5040);

  HexDigits: set of Char = ['0'..'9', 'A'..'Z', 'a'..'z'];

  Origin: Point = (X: 0.0; Y: 0.0);


Konstanten strukturierten Typs

Siehe auch	Typisierte Konstanten

Die Deklaration einer Konstanten strukturierten Typs spezifiziert den Wert von jeder einzelnen Komponente der Struktur.

Object Pascal unterstützt die Deklaration von Konstanten der folgenden Typen:

Array

Record

Set

Zeiger

Konstanten vom Typ Datei und Konstanten vom Typ array oder record, die Komponenten vom Typ file enthalten sind nicht erlaubt.


Siehe auch

Zeigertyp Konstanten

Konstanten prozeduralen Typs

Konstanten einfachen Typs

String-Typ-Konstanten


Konstanten vom Typ Array

Beispiel 	Konstanten strukturierten Typs

Eine Konstante vom Typ Array deklariert ein Array mit vorinitialisierten Elementen.

Die Deklaration einer Konstanten vom Typ Array legt die Werte der Komponenten fest. Die Komponenten einer Konstanten vom Typ Array können jeden Typ außer Datei besitzen.

Zeichen-Arrays

Konstanten vom Typ packed string (Zeichen-Arrays) können als einzelne Zeichen oder als String spezifiziert werden.

Zero-Based Zeichen-Arrays

Der Indexwert des ersten Elementes eines zero-based Zeichen-Arrays ist 0 und der Indexwert des letzen Elementes ist ein positiver Integerwert (außer 0).

Ein zero-based Zeichen-Array kann mit einem String initialisiert werden, der kürzer ist als das Array. Die überzähligen Stellen werden mit Null (#0) aufgefüllt, man erhält also einen null-terminated String.

Mehrdimensionale Array-Konstanten

Mehrdimensionale Array-Konstanten werden durch Einschluss der Konstanten jeder Dimension in Klammern definiert, diese Klammerpaare werden durch Kommata getrennt.

Die innerste Konstante entspricht der Dimension, die am weitesten rechts steht.


Beispiele für Konstanten von Typ Array
Beispiele

Im folgenden Beispiel wird die Array-Konstante StatStr gebildet.

type

  TStatus = (Aktiv, Passiv, Wartend);

  TStatusMap = array[TStatus] of string;

const

  StatStr: TStatusMap = ('Aktiv', 'Passiv', 'Wartend');

Die Komponenten von StatStr sind:

  StatStr[Active] = 'Aktiv'

  StatStr[Passive] = 'Passiv'

  StatStr[Waiting] = 'Wartend' }

Im folgenden Beispiel wird ein mehrdimensionales Array Maze deklariert und initialisiert.

type

    TCube = array[0..1, 0..1, 0..1] of Integer;

  const

    Maze: TCube = (((0, 1), (2, 3)), ((4, 5), (6, 7)));

Die Werte für das Array Maze sind:

  Maze[0, 0, 0] = 0

  Maze[0, 0, 1] = 1

  Maze[0, 1, 0] = 2

  Maze[0, 1, 1] = 3

  Maze[1, 0, 0] = 4

  Maze[1, 0, 1] = 5

  Maze[1, 1, 0] = 6

  Maze[1, 1, 1] = 7


Konstanten vom Typ Zeiger
Zeigerkonstanten

Siehe auch	Beispiel 	Typisierte Konstanten

Eine Konstante vom Typ Zeiger ermöglicht es einen Zeiger konstant vorzuinitialisieren. Die Deklaration einer Konstante vom Typ Zeiger benutzt typischerweise einen konstanten Adreßausdruck, um einen Zeigerwert zu spezifizieren.

Eine typisierte Konstante vom Typ PChar kann mit einer String-Konstante initialisiert werden.


Siehe auch

PChar

Zeigertypen


Beispiel

Das folgende Beispiel deklariert Zeigerkonstanten.

type

  TDirection = (Links, Rechts, Oben, Unten);

  PNode = ^Node;

  TNode = record

    Next: PNode;

    Symbol: string;

    Value: TDirection;

  end;

const

  S1: string[4] = 'UNTEN';

  S2: string[2] = 'OBEN';

  S3: string[5] = 'RECHTS';

  S4: string[4] = 'LINKS';

  N1: TNode = (Next: nil; Symbol: 'UNTEN'; Value: Down);

  N2: TNode = (Next: @N1; Symbol: 'OBEN'; Value: Up);

  N3: TNode = (Next: @N2; Symbol: 'RECHTS'; Value: Right);

  N4: TNode = (Next: @N3; Symbol: 'LINKS'; Value: Left);

var

  DirectionTable: PNode = @N4;


Prozedurale Konstanten

Siehe auch	Beispiel 	Typisierte Konstanten

Eine Prozdurale Konstante ermöglicht es, prozedurale Typen vorzuinitialisieren.

Eine Konstante prozeduralen Typs muß einen Bezeichner spezifizieren, der zuweisungskompatibel zum Typ der Prozedur oder Funktion mit dem Typ der Konstanten ist. Eine weitere Möglichkeit ist die Spezifizierung von Nil.


Siehe auch

Prozedurale Typen

Typisierte Konstanten


Beispiel

Das folgende Beispiel weist eine Prozedur einer Typ-Konstanten zu.

type

  TErrorProc = procedure(ErrorCode: Integer);

procedure DefaultError(ErrorCode: Integer);

begin

  WriteLn('Fehler ', FehlerCode, '.');

end;

const

  ErrorHandler: TErrorProc = DefaultError;


Record-Konstanten

Siehe auch	Beispiel 	Konstanten strukturierten Typs

Mit einer Record-Konstanten ist es möglich, Felder eines Records vorzuinitialisieren.Die Deklaration einer Record-Konstanten spezifiziert den Bezeichner und den Wert jedes Feldes des Records. Diese Werte werden in Klammern eingeschlossen und durch Kommata getrennt.

Die Felder müssen in der gleichen Reihenfolge wie in der Definition des Record aufgeführt werden.

Wenn ein Record ein Feld vom Typ file enthält, können für diesen Record-Typ keine Konstanten deklariert werden.

Wenn ein Record eine Variante enthält, so können nur die Felder der ausgewählten Variante spezifiziert werden.

Wenn eine Variante ein Bezeichner-Feld enthält, so muß dessen Wert spezifiziert sein.


Siehe auch

Records

Typisierte Konstanten


Beispiel

Das folgende Beispiel deklariert die Record-Konstante TPoint.

type

  TPoint = record

    X, Y: Single;

  end;

  TVector = array[0..1] of Point;

  TMonth = (Jan, Feb, Mär, Apr, Mai, Jun, Jly, Aug, Sep, Okt, Nov, Dez);

  TDate = record

    D: 1..31;

    M: Month;

    Y: 1900..1999;

  end;

const

  Origin: TPoint = (X: 0.0; Y: 0.0);

  Line: TVector = ((X: -3.1; Y: 1.5), (X: 5.8; Y: 3.0));

  SomeDay: TDate = (D: 2; M: Dec; Y: 1960);


Mengen-Konstanten

Siehe auch	Beispiel 	Konstanten strukturuerten Typs

Eine Mengen-Konstante ermöglicht es Ihnen, die Werte einer Menge konstant vorzuinitialisieren.

Die Deklaration einer Mengen-Konstanten spezifiziert den Wert einer Menge mit einem konstanten Ausdruck.


Siehe auch

Mengen

Set-Typ

Typisierte Konstanten


Beispiel

Das folgende Beispiel deklariert eine Mengenkostante für Ziffern und Buchstaben.

type

  Digits = set of 0..9;

  Letters = set of 'A'..'Z';

const

  EvenDigits: Digits = [0, 2, 4, 6, 8];

  Vowels: Letters = ['A', 'E', 'I', 'O', 'U', 'Y'];

  HexDigits: set of '0'..'z' = ['0'..'9', 'A'..'F', 'a'...f'];


Einfache Konstanten

Siehe auch	Beispiel 	Typisierte Konstanten

Die Deklaration einer einfachen Konstanten spezifiziert den Wert der Konstanten.

Sie können den Wert einer typisierten Konstanten dadurch spezifizieren, daß Sie einen konstanten Adreßausdruck verwenden.

Da e sich bei einer typisierten Konstanten eigentlich um eine Variable mit einem konstanten Wert handelt, kann sie nicht bei der Deklaration anderer Konstantentypen verwendet werden.


Siehe auch

Typen

Typisierte Konstanten


Beispiel

Das folgende Beispiel deklariert einfache Konstanten.

const

  Maximum: Integer = 9999;

  Factor: Real = -0.1;

  Breakchar: Char = #3;


String Konstanten

Siehe auch	Beispiel 	Typisierte Konstanten

Die Deklarartion einer typisierten Konstante vom Typ String bestimmt lediglich die String Konstant:

Um eine typisierte Konstante mit kurzem String zu deklarieren, nehmen Sie eine Längenangabe in die Deklaration auf.


Siehe auch

String-Typen

Typisierte Konstanten


Beispiele für Konstanten von Typ String
Beispiele für String-Typ-Konstanten

Das folgende Beispiel deklariert lange String-Typ-Konstanten.

const

  Heading: string = 'Abschnitt';

  NewLine: string = #13#10;

  TrueStr: string = 'Ja';

  FalseStr: string = 'Nein';

Das folgende Beispiel deklariert eine kurze String-Typ-Konstante.

const

  ShortStr: string[5] = 'Kurz';.


Ausdrücke

Siehe auch

Ausdrücke sind eine Kombination von Operatoren und Operanden, die zu einem einzigen Wert führen.

Diese Operanden sind:

Konstanten

Funktionsaufrufe

Prozedur-Anweisungen

Mengen Konstruktoren

Variablen

Unterausdrücke können eingeklammert werden, um die Reihenfolge der Abarbeitung zu verändern.


Siehe auch

@ Operator

Blöcke

Kommentare

Konstanten Deklarationen

Funktionsaufrufe

Precedenzregeln der Operatoren

Set-Typen

Anweisungen

Wert Typumwandlungen

Variablen Referenzen


Funktionsaufrufe

Siehe auch

Ein Funktionsaufruf aktiviert eine Funktion, die durch folgendes spezifiziert ist:

Einen Funktionsbezeichner

Einen Methodenkennzeichner

Einen qualifizierten Methodenkennzeichner

Eine Variablen-Referenz prozeduralen Typs

Wenn die entsprechende Funktionsdeklaration eine Liste formaler Parameter enthält, so muß der Funktionsaufruf eine Liste aktueller Parameter beinhalten. Jeder Parameter übernimmt den Platz eines formalen Parameters gemäß den Parameter-Regeln.

Object Pascal ermöglicht das Löschen des Ergebnisses eines Funktionsaufrufs, wobei die Funktion prinzipiell als Prozedur-Anweisung behandelt wird.


Siehe auch

Methodenaktivierung

Qualified-Methodenaktivierungen

Parameter

Prozedurale Typen


Wert-Typumwandlungen

Siehe auch	Beispiel

Wert-Typumwandlung ist der Vorgang den Typ eines Ausdrucks von einem Typ in einen anderen Typ zu verwandeln.

Der Typ des Ausdrucks und der spezifizierte Typ müssen beide sein:

Ein ordinaler Typ oder

Ein Zeiger Typ

Für ordinale Typen wird der resultierende Wert folgendermaßen berechnet: Der Ausdruck wird unter Zuhilfenahme von Abschneidungen oder Verlängerungen, wenn der Wert des spezifizierten Typs von dem des Ausdruckes abweicht. Wenn eine Verlängerung vorgenommen wird, so wird immer das Vorzeichen des Wertes bewahrt.

Wert-Typumwandlungen operieren auf Werten und können nicht von einem Qualifizierer gefolgt werden.


Beispiel

Die folgenden Anweisungen sind Beispiele für Wert-Typumwandlungen.

Integer('A')

Char(48)

Boolean(0)

Color(2)

Longint(@Buffer)


Siehe auch

Wert Typumwandlungen


Verwenden prozeduralen Typen in Ausdrücken
Verwenden prozeduraler Typen in Ausdrücken

Siehe auch	Beispiel

Das Verwenden einer prozeduralen Variablen in einer Anweisung eines Ausdrucks ruft die Prozedur oder Funktion, die in der Variablen gespeichert ist, auf. Dennoch erkennt der Kompiler, daß, wenn auf der linken Seite einer Zuweisung eine prozedurale Variable steht, auf der rechten Seite ein prozeduraler Wert stehen muß. Unglücklicherweise gibt es Situationen, in denen der Kompiler nicht die gewünschte Aktion aus dem Kontext ableiten kann.

Prozedurale Typen und der @-Operator

Wenn Sie den Adreßoperator (@) einem Prozedur- oder Funkrionsbezeichner hinzufügen, so wird das Argument in einen Zeiger verwandelt und der Kompiler wird daran gehindert eine Prozedur aufzurufen.

Der @-Operator wird häufig verwendet, um einer prozeduralen Variable einen nicht typisierten Zeiger zuzuweisen.

Um die Speicheradresse einer prozeduralen Variable und nicht die in ihr gespeicherte Adresse zu erhalten, verwenden Sie einen doppelten Adreßoperator (@@).


Beispiel

type

  IntFunc = function: Integer;

var

  F: IntFunc;

  N: Integer;

function ReadInt: Integer;

var

  I: Integer;

begin

  Read(I);

  ReadInt := I;

end;

begin

  F := ReadInt;   { weist einen procedurealen Wert zu }

  N := ReadInt;   { weist einer Funktion Result zu }

end.


Siehe auch

@ Operator

Prozedurale Typen


Spezielle Symbole

Siehe auch

Spezielle Symbole sind Zeichen aus dem ASCII-Zeichensatz, die eine vordefinierte Bedeutung haben. Sie können deshalb in Ihren Programmen nur in der durch Object Pascal definierten Bedeutung verwendet werden.

Die folgenden einzelnen Zeichen sind spezielle Symbole:

+     -     *     /     =     <     >     [     ]     .     ,     (     )     :     ;     ^     @     {     }     $     #

Die folgenden Zeichenpaare sind spezielle Symbole:

<=     >=     :=     ..     (*  *)     (.  .)

Manche der speziellen Symbole sind Operatoren.

Manche speziellen Symbole haben ein Zeichenpaar, das die gleiche Funktion erfüllt.

Zeichen	Gleichartiges Zeichenpaar

[	(.

]	).

{	(*

}	*)

Object Pascal verwendet die folgenden Untermengen des ASCII-Zeichensatzes:

Buchstaben -- das englische Alphabet, A bis Z und a bis z

Ziffern -- die arabischen Zahlen von 0 bis 9

Hexadezimale Ziffern -- die arabischen Ziffern von 0 bis 9, die Buchstaben A bis F und a bis f.

Leerzeichen -- das Leerzeichen (ASCII 32) und alle ASCII-Kontrollzeichen (ASCII 0 bis 31), inklusive des Zeilenende- und des Wagenrücklaufzeichens (ASCII 13)


Siehe auch

Kommentare

Operatoren


Zahlen

Die normale Dezimaldarstellung wird für Zahlen verwendet, die Konstanten vom Typ Integer oder Real sind.

Zahlen mit Kommastellen oder Exponenten sind Real-Konstanten. Andere Dezimalzahlen sind Integerkonstanten, der Wertebereich ist zwischen - 2147483648 und 2147483647.

Hexadezimale Zahlen

Hexadezimale Integerkonstanten haben ein Dollarzeichen ($) als Präfix.

Der Wertebereich hexadezimaler Integerkonstanten liegt zwischen $00000000 und $FFFFFFFF.

Ingenieurdarstellung

Die Ingenieurdarstellung (E oder e gefolgt von einem Exponenten) wird als "mal Zehn hoch" gelesen. Zum Beispiel:

7E-2  bedeutet  7 x 10-2

12.25e+6  oder  12.25e6  bedeutet  12.25 x 10+6.


Zeichenketten

Beispiel

Eine Zeichenkette ist eine Folge von null oder mehr Zeichen des erweiterten ASCII-Zeichensatzes. Diese Zeichenkette muß in einer Programmzeile stehen und in Apostrophen eingeschlossen sein.

Die Zeichenkette, bei der zwischen den Apostrophen nichts steht ist der Null-String.

Zwei aufeinanderfolgende Apostrophen in einer Zeichenkette stehen für ein einzelnes Apostroph.

Das Längenattribut einer Zeichenkette ist die momentane Anzahl an Zeichen inerhalb der Apostrophen. Die maximale Länge für eine Zeichenkette ist 255 Zeichen.

Kontrollzeichen

Als eine Erweiterung zu Object Pascal gestattet der Compiler die Verwendung von erweiterten Zeichen in Zeichenketten.

Das #-Zeichen gefolgt von einer Integerkonstanten zwischen 0 und 255 steht für das entsprechende Zeichen aus dem ASCII-Zeichensatz.

Es dürfen zwischen dem #-Zeichen und der Integerkonstanten keine Leerzeichen stehen.

Wenn mehrere Kontrollzeichen in der Zeichenkette aufeinanderfolgen, so darf zwischen diesen kein Leerzeichen stehen.

String-Kompatibilität

Eine Zeichenkette der Länge Null ist nur mit Strings kompatibel.

Eine Zeichenkette der Länge 1 ist mit jedem Char und jedem string-Typ kompatibel.

Eine Zeichenkette der Länge N, wobei N größer oder gleich 2 ist, ist kompatibel zu:

Jedem String-Typ

Packed Arrays aus N Zeichen

Dem Typ PChar, wenn in der Kompilerdirektive {$X+}. die erweiterte Syntax zugelassen ist.


Beispiel

'BORLAND'        { BORLAND }

'Sie werden sehen'    {Sie werden sehen }

''''             { ' }

''               { Nullstring }

' '              { Leerzeichen }


Kommentare

Siehe auch	Beispiel

Wenn Sie den Sinn eines Code-Teils verdeutlichen wollen, so können Sie erklärende Kommentare angeben, die Sie in Klammern { } oder Sternklammern (* *) einschließen müssen.

Der Text zwischen den Kommentarzeichen wird vom Kompiler ignoriert.

Sie können kein Zeichen, das einen Kommentar beendet in den Kommentar einschließen, da dies vom Kompiler als das Ende des Kommentares angesehen wird.

Ein Kommentar, bei dem nach der Kommentareröffnung { oder (* sofort ein Dollar-Zeichen ($) folgt, ist eine Kompilerdirektive. Eine Beschreibung des Kompilerbefehls folgt auf das $-Zeichen.

Sie können einen einzeiligen Kommentar auch dadurch erstellen, indem Sie zwei Schrägstriche vor den Text stellen. Der Compiler ignoriert dann alles bis zum Ende der Zeile


Siehe auch

Blöcke


Beispiel

  { Beliebiger Text, der keine rechte Klammer enthält }

  (* beliebiger Text, der keinen Stern/keine rechte Klammer enthält*)

// beliebiger Text nach doppeltem Schrägstrich bis zum Ende der Zeile


Tokens

Siehe auch

Tokens sind die kleinste sinnvolle Texteinheit in Object Pascal. Tokens sind:

Zeichenketten

Bezeichner

Labels

Zahlen

Reservierte Wörter

Spezielle Symbole

Wenn Sie zwei aufeinanderfolgende Tokens in Ihrem Programm verwenden, so müssen diese beiden durch einen Separator getrennt werden, wenn einer der Tokens ein reserviertes Wort, ein Bezeichner, ein Label oder eine Zahl ist. Sie können Separatoren außer bei Zeichenketten nicht als Teil eines Tokens verwenden.


Siehe auch

Comments

Standard Directives


Labels

Siehe auch

Ein Label ist eine Zahlenfolge zwischen 0 und 9999 (führende Nullen sind nicht signifikant), die das Ziel eines Goto-Befehls darstellt.

Als Erweiterung zu Standard-Pascal ist es in Object Pascal auch möglich Bezeichner als Labels zu verwenden.


Siehe auch

Blöcke

Label (reserviertes Wort)


Anweisungen

Siehe auch

Anweisungen beschreiben algorithmische Aktionen, die ein Programm ausführen kann.

Es gibt zwei Grundtypen von Anweisungen:

Einfache Anweisungen

Strukturierte Anweisungen

Einfache Anweisungen

Einfache Anweisungen können einen Wert zuweisen, eine Prozedur oder Funktion aufrufen oder das Programm auf eine andere Anweisung setzen.

Die einfachen Anweisungen, die Object Pascal unterstützt sind:

Zuweisungsanweisung (:=)

Goto-Anweisung

Prozedur-Anweisung

Strukturierte Anweisungen

Strukturierte Anweisungen sind aus anderen Anweisungen zusammengesetzt, die sequentiell, konditional oder wiederholt ausgeführt werden.

Die strukturierten Anweisungen, die Object Pascal unterstützt sind:

Zusammengesetzte Anweisung

Bedingte Anweisung

Schleifen

With-Anweisung


Siehe auch

Blöcke


Zuweisungsanweisungen

Siehe auch	Beispiel

Zuweisungsanweisungen weisen den Wert des Ausdrucks rechts von dem Zuweisungsoperator dem Bezeichner auf der linken Seite zu. Der Zuweisungsoperator, der die beiden Seiten voneinander trennt, ist :=.

Zuweisungsanweisungen können Sie benutzen, um:

Den aktuellen Wert einer Variable durch den im Ausdruck spezifizierten Wert zu ersetzen.

einen Ausdruck zu spezifizieren, dessen Wert von einer Funktion zurückgeliefert wird.

Objekttyp-Zuweisung

Sie können einer Instanz eines Objekttyps eine Instnaz jeder seiner abgeleiteten Typen zuweisen. Diese Zuweisung bewirkt eine Abbildung des abgeleiteten Typs auf den Speicherbereich des übergeordneten Typs.

Hinweis:	Die Zuweisung an eine Instanz stellt keine Initialisierung der Instanz dar.


Siehe auch

Zuweisungsverträglichkeit

Zuweisungsoperator

Object-Typen

Typverträglichkeit


Beispiele

X := Y + Z;

Done := (I >= 1) and (I < 100);

Hue1 := [Blue, Succ(C)];

I := Sqr(J) - I * K;


Goto-Anweisungen

Siehe auch

Eine goto-Anweisung verschiebt die Programmausführung an die spezifizierte Anweisung.

Bei der Verwendung von goto-Anweisungen sollten Sie folgende Regeln beachten:

Das Label, das von der goto-Anweisung referenziert wird, muss im gleichen Block liegen, wie die goto-Anweisung. Sie können nicht in oder aus einer Prozedur oder Anweisung springen.

Das Springen in eine strukturierte Anweisung von außerhalb der strukturierten Anweisung kann unvorhersehbare Effekte haben, dennoch wird vom Kompiler kein Fehler ausgewiesen.

Für einen guten Programmierstil sollten Sie die Verwendung von goto-Anweisungen möglichst vermeiden.


Siehe auch

Goto (reserviertes Wort)

Gültigkeitsbereich


Prozedurale Anweisungen

Siehe auch

Prozedurale Anweisungen aktivieren eine Prozedur durch eine der folgenden Möglichkeiten:

Einen Prozedur-Bezeichner

Einen Methoden-Kennzeichner

Einen qualifizierten Methoden-Kennzeichner

Eine Variablen-Referenz prozeduralen Typs.

Wenn die entsprechende Prozedurdeklaration eine Liste formaler Parameter enthält, so muß der Prozeduraufruf eine Liste aktueller Parameter beinhalten.

Jeder Parameter übernimmt den Platz eines formalen Parameters gemäß den Parameter-Regeln.


Siehe auch

Funktionsaufrufe

Methodenaktivierung

Parameter

Prozedurale Typen

Prozedur (reserviertes Wort)

Qualified-Methodenaktivierungen

Variablen Referenzen


Zusammengesetzte Anweisungen

Siehe auch	Beispiel	Sprachdefinition

Zusammengesetzte Anweisungen geben an, daß die enthaltenen Anweisungen in der Reihenfolge ausgeführt werden sollen, in der sie aufgeschrieben sind. Die zusammengesetzte Anweisung wird wie eine einzige Anweisung behandelt, was an den Stellen wichtig ist, wo eine einzelne Anweisung erwartet wird.

Die reservierten Worte begin und end schließen die Anweisungen ein. Einzelne Anweisungen werden durch Semikolons getrennt.


Beispiel

Im folgenden ein Beispiel für eine zusammengesetzte Anweisung:

begin

  Z := X;

  X := Y;

  Y := Z;

end;


Siehe auch

Begin..end

Blöcke


Schleifen

Siehe auch	Sprachdefinition

Schleifen ermöglichen es, eine oder mehrere Anweisungen wiederholt auszuführen, solange oder bis eine Bedingung erfüllt ist.

Es gibt drei Arten von Schleifen:

for..to/downto..do

while...do

repeat..until

Welche Schleife Sie benutzen sollten hängt von zwei Kriterien ab:

Die Aktionen, die Sie ausführen wollen.

Wieviel Sie über die Bedingungen vor Eintritt in die Schleife wissen.

Schleife	Verwenden, wenn

for	Sie die Anzahl der Schleifendurchläufe genau kennen.

while...do	Sie vor Eintritt in die Schleife die Bedingung prüfen möchten.

repeat...until	Sie möchten, daß die Schleife mindestens einmal ausgeführt wird, bevor die Bedingung getestet wird.

Sie können die Standarddirektiven Break und Continue zur Kontrolle des Schleifendurchlaufs verwenden.


Siehe auch

Bedingte Anweisungen

Boolesche Ausdrücke


Bedingte Anweisungen

Siehe auch

Bedingte Anweisungen geben Ihnen die Möglichkeit, zu kontrollieren, ob bestimmte Ausdrücke ausgewertet werden sollen oder nicht.

Es gibt zwei Arten von bedingten Ausdrücken:

if-Anweisungen

case-Anweisungen

Verwenden Sie die if-Anweisung, wenn es nur zwei Möglichkeiten gibt.

Verwenden Sie die case-Anweisung, wenn es mehr Möglichkeiten gibt.


Siehe auch

Boolesche Ausdrücke

Schleifen


Boolesche Ausdrücke

Siehe auch

Boolesche Ausdrücke werden zu True oder False ausgewertet. Alle Schleifen und bedingten Ausdrücke hängen von booleschen Ausdrücken ab.

Ein boolescher Ausdruck vergleicht zwei Operanden und liefert ein Ergebnis, das einer Variable vom Typ Boolean zugewiesen werden muß.

Die booleschen Operatoren and und or arbeiten auf Paaren von booleschen Ausdrücken. Object Pascal unterstützt zwei verschiedene Modelle der Code-Generierung für diese Operatoren.

Vollständige Auswertung

Short-circuit Auswertung

Das Modell der Auswertung wird durch die Kompilerdirektive $B ausgewählt. Als Standardeinstellung {$B-} verwendet der Kompiler den Short-circuit Modus. In der Einstellung {$B+} verwendet der Kompiler das Modell der vollständigen Auswertung.


Siehe auch

Boolesche Operatoren

Boolesche Typen

Relationale Operatoren


Parameter

Siehe auch

Parameter ermöglichen es, Daten an Prozeduren ud Funktionen zu übertragen und von diesen zu erhalten.

Die Deklaration einer Prozedur oder Funktion legt die Liste der formalen Parameter fest.

Jeder formale Parameter, der in einer Liste der formalen Parameter deklariert ist, ist lokal zu der Prozedur oder Funktion in der er deklariert wird. Auf die Parameter kann innerhalb des zu der Prozedur oder Funktion gehörenden Blocks zugegriffen werden.

Es gibt fünf Arten von Parametern:

Wert Parameter	Parametergruppe ohne vorhergehendes var, aber gefolgt von einem Typ.

Konstante Parameter	Parametergruppe nach const gefolgt von einem Typ.

Variablen-Parameter	Parametergruppe mit vorhergehendem var gefolgt von einem Typ.

Nicht typisierte Parameter	Parametergruppe mit vorhergehendem var oder const, nicht gefolgt von einem Typ.

Offene Array-Parameter	Parametergruppe für Parameter vom Typ Array.


Siehe auch

Funktionsaufrufe

Funktionen

Prozeduren


Wert Parameter

Siehe auch

Ein formaler Wert Parameter ist lokal zu der deklarierenden Prozedur oder Funktion, es sei denn er erhält seinen initialen Wert vom entsprechenden aktuellen Parameter der aufrufenden Funktion oder Prozedur.

Änderungen, die an einem formalen Wert Parameter gemacht werden beeinträchtigen den Wert des aktuellen Parameters nicht.

Der aktuelle Parameter eines Wert Parameters in einer Prozedur-Anweisung oder einem Funktionsaufruf muß ein Ausdruck sein und sein Wert  darf nicht der Typ Datei oder eine Struktur sein, die eine Komponente vom Typ Datei enthält.

Der aktuelle Parameter muß zuweisungskompatibel zum Typ des formalen Parameters sein.


Siehe auch

Funktionsaufrufe

Parameter

Wert Parameter


Konstante Parameter

Siehe auch

Ein formaler konstanter Parameter ist eine lokale read-only Variable, die ihren Wert von dem entsprechenden aktuellen Parameter erhält.

Zuweisungen an einen formellen konstanten Parameter sind nicht erlaubt, genauso kann ein formaler konstanter Parameter nicht als aktueller Parameter an eine Prozedur oder Funktion weitergegeben werden.

Der zu einem formalen konstanten Parameter gehörende aktuelle Parameter in einer Prozedur oder einer Funktion muß ein Ausdruck sein. Der Wert des Ausdrucks darf nicht der Typ Datei oder ein strukturierter Typ sein, der den Typ Datei enthält.

Wenn Sie verhindern möchten, daß ein formaler Parameter während der Ausführung einer Funktion oder Prozedur seinen Wert ändert, so verwenden Sie einen konstanten Parameter an Stelle eines Wert Parameters. Konstante Parameter bieten Schutz gegen das unbeabsichtigte Zuweisen eines neuen Wertes an einen formalen Parameter.

Bei strukturierten Parametern oder String-Parametern generiert der Kompiler effizienteren Code, wenn konstante Parameter an Stelle von Wert Parametern verwendet werden.


Siehe auch

Funktionsaufrufe

Parameter


Variablen-Parameter

Siehe auch

Ein Variablen-Parameter übergibt eine Variable per Referenz an die Prozedur oder Funktion. Das bedeutet, daß die Adresse des Parameters übergeben wird und so der Wert des Parameters verwendet und verändert werden kann.

Damit der aktuelle Parameter ein Variablen-Parameter ist, muß der Parameter mit einre Variablen-Referenz übergeben werden. Eine Variablen-Referenz wird dadurch erzeugt, daß man das Schlüsselwort var in der Parameterliste der Deklaration der Prozedur oder Funktion verwendet.

Der formale Variablen-Parameter repräsentiert die aktuelle Variable wenn die Prozedur oder Funktion aktiv ist. Alle Veränderungen des Wertes des formalen Variablen-Parameters wirken sich auf den aktuellen Parameter aus.

Hinweis	Der Typ Datei kann nur als Variablen -Parameter übergeben werden.

Innerhalb der Prozedur oder Funktion greift jede Referenz auf den formalen Variablen-Parameter auf den aktuellen Parameter selbst zu. Der Typ des aktuellen Parameters muß mit dem Typ des formalen Parameters identisch sein (Diese Restriktion können Sie durch nicht typisierte Parameter umgehen).

Wenn das Referenzieren des aktuellen Parameters eine Indizierung eines Arrays oder das Auffinden eines Zeigerobjektes beinhaltet, so werden diese Aktionen vor der Aktivierung der Prozedur oder Funktion ausgeführt.

Die Regeln der Objekt-Typ Zuweisungskompatibilität gelten auch für Variablen-Parameter vom Typ Objekt. Bei einem formalen Parameter vom Typ T1 kann der aktuelle Parameter auch vom Typ T2 sein, wenn T2 im Wertebereich von T1 liegt.


Siehe auch

Zuweisungsverträglichkeit

Funktionsaufrufe

Parameter

Untypisierte Parameter


Nicht typisierte Parameter

Siehe auch	Beispiel

Wenn ein formaler Parameter ein nicht typisierter Parameter ist, so kann der entsprechende aktuelle Parameter jede Variablen- oder Konstanen-Referenz sein, egal welchen Typ diese hat.

Ein nicht typisierter Parameter, der mit dem Sclüsselwort var deklariert wird kann verändert werden.

Ein nicht typisierter Parameter, der mit em Schlüsselwort const deklariert wurde ist read-only.

Innerhalb der Prozedur oder Funktion ist der nicht typisierte Parameter typlos. Er ist inkompatibel mit allen anderen Typen, es sei denn, ihm wird durch eine Variablen-Typumwandlung ein spezieller Typ zugewiesen.

Nicht typisierte Parameter ermöglichen eine größere Flexibilität, sie können aber in der Verwendung riskanter sein, da der Kompiler die Operationen nicht auf ihre Legalität überprüfen kann.


Beispiel

function Equal(var Source, Dest; Size: Integer): Boolean;

type

  TBytes = array[0..MaxInt - 1] of Byte;

var

  N: Integer;

begin

  N := 0;

  while (N < Size) and (TBytes(Dest)[N] = TBytes(Source)[N]) do

    Inc(N);

  Equal := N = Size;

end;


Offene Array-Parameter

Siehe auch	Beispiel

Mit offenen Array-Parametern ist es möglich, Arrays verschiedener Größe an eine Prozedur oder Funktion zu übergeben.

Die Syntax für die Deklaration von open-array Parametern als formale Parameter ist folgende:

array of T

T muß ein Typ-Bezeichner sein. Der aktuelle Parameter muß eine Variable vom Typ T oder eine Array-Variable mit Elementen vom Typ T sein.

Innerhlb der Prozedur oder Funktion verhält sich der formale Parameter, als wäre er folgendermaßen deklariert.

array[0..N - 1] of T

wobei N die Anzahl der Elemente im aktuellen Parameter ist. Der Indexbereich des aktuellen Parameters wird auf die Integer 0 bis N-1 abgebildet. Wenn der aktuelle Parameter eine einfache Variable vom Typ ist, so wird diese behandelt, als sei sie ein Array aus einem Element.

Sie können auf die Elemente des formalen open-array Parameters nur einzeln zugreifen. Zuweisungen an das gesamte offene Array sind illegal.

Sie können offene Arrays an andere Prozeduren oder Funktionen nur als open-array Parameter oder als nicht typisierte Variablen-Parameter übergeben.

Open-Array Parameter können als Wert Parameter, konstanter Parameter oder Variablen-Parameter verwendet werden, die Einschränkungen bleiben bestehen.

Für einen open-array Wert Parameter erzeugt der Kompiler eine lokale Kopie des aktuellen Parameters im Stack-Bereich der Prozedur oder Funktion. Deshalb achten Sie darauf, den lokalen Speicher nicht zu überlasten, wenn Sie große Arrays als open-array Wert Parameter übergeben. Um sicherzugehen, daß der Stack nicht überläuft, verwenden Sie besser var of const, wenn Sie open-array Wert Parameter übergeben.

Wenn bei einem offenen Zeichen-Array ein leerer String übergeben wird, so wird dieser in einen String mit einem Element NULL (#0) umgewandelt. Die Anweisung PrintStr("") entspricht also PrintStr(#0).

Wenn der Elementtyp eines open-array Parameters Char ist, so kann der aktuelle Parameter eine String-Konstante sein.

Die folgenden Standardfunktionen können auf open-array Parameter angewendet werden.

Funktion	Rückgabewert

Low	Null

High	Der Indexwert des letzten Elementes im aktuellen Array-Parameter.

SizeOf	Die Größe des aktuellen Array-Parameters.

Konstruktion eines offenen Array-Parameters

Einen offenen Array-Parameter können Sie umgehend konstruieren, ohne eine Variable oder Konstante zu deklarieren, indem Sie die gewünschten Array-Elemente, durch Kommata getrennt, in Klammer einschließen. Anstatt also ein Array zu deklarieren und zu füllen, können Sie es auf einmal konstruieren und übergeben:

MyProcedure([3, 2, 1900, 42]);


Siehe auch

Array-Typen

Parameter

Typensichere offene Arrays


Beispiel

procedure Clear(var A: array of Double);  {weist Null jedem Element eines Double-Arrays zu}

var

  I: Integer;

begin

  for I := 0 to High(A) do A[I] := 0;

end;

function Sum(const A: array of Double): Double;   {berechnet die Summe aller Elemente in einem Double-Array}

var

  I: Integer;

  S: Real;

begin

  S := 0;

  for I := 0 to High(A) do S := S + A[I];

  Sum := S;

end;

procedure PrintStr(const S: array of Char);  {Erlaubt einer Stringkonstante an eine Procedure übergeben zu werden }

var

  I: Integer;

begin

  for I := 0 to High(S) do

    if S[I] <> #0 then Write(S[I]) else Break;

end;


Typenvariante offene Array-Parameter

Siehe auch

Das neue Konstrukt array of const erlaubt einem offenen Array von Objekten die mehr als ein Typ beinhalten an eine Prozedur oder Funktion in einer Typ-sicheren Art und Weise übergeben zu werden. Es ist möglich eine Formatierungsroutine zu deklarieren die jede Anzahl von Elementen verschiedenen Typs akzeptiert.

Die folgende Prozedurdeklaration zeigt den Gebrauch eines array of const in der Deklaration einer Stringformatierungsroutine. Der Parameter Args akzeptiert ein offenes Array das jede Anzahl von Variablen enthält und jeden Typ:

procedure FmtStr(var Result: string; const Format: string; const Args: array of const);

Der Compiler behandelt diese Konstrukt array of const genauso wie ein array of TVarRec.


Siehe auch

Offene Array Parameter


External Deklarationen

Siehe auch 	Beispiel

External Deklarationen ermöglichen:

Verwenden getrennt kompilierter Prozeduren und Funktionen, die in Assemblersprache geschrieben sind.

Import von Proceduren und Funktionen aus DLLs

External Direktiven, die nur aus dem reservierten Wort external bestehen werden in Verbindung mit der Direktive {$L filename} verwendet, um eine Verbindung mit externen Prozeduren und Funktionen in  .OBJ-Dateien herzustellen.

External Direktiven, die einen DLL-Namen spezifizieren ( und zusätzlich optional einen Import-Namen und eine Zählungsnummer besitzen) werden verwendet, um Funktionen und Prozeduren aus einer DLL zu importieren.

Die External Direktive übernimmt die Aufgabe der Deklaration und der Anweisungsteile einer importierten Funktion oder Prozedur.

Abgesehen von diesem Unterschied verhalten sich importierte Funktionen und Prozeduren wie normale Prozeduren und Funktionen.


Beispiele

Folgende Beispiele zeigen die Deklaration von External Prozeduren

procedure MoveWord(var Source, Dest; Count: Integer); external;

procedure MoveLong(var Source, Dest; Count: Integer); external;

procedure FillWord(var Dest; Data: Integer; Count: Integer); external;

procedure FillLong(var Dest; Data: Longint; Count: Integer); external;

Folgende External Deklaration importiert eine Funktion namens MessageBox aus einer DLL namens 'user32.dll' (die Teil der Windows API ist):

function MessageBox(HWnd: Integer; Text, Caption: PChar
Flags: Integer): Integer; stdcall;
external 'user32.dll' name 'MessageBoxA';


Siehe auch

Dynamic-Link Libraries

Funktionen

Prozeduren


Methodendeklarationen

Siehe auch	Beispiel

Die Deklaration einer Methode in einem Objekttyp entspricht einer forward Deklaration dieser Methode.

Irgendwo nach der Objekttyp-Deklaration und im selben Gültigkeitsbereich wie die Objekttyp-Deklaration muß die Methode durch eine definierende Deklaration implementiert werden.

Für Prozedur- und Funktions -Methoden hat die definierende Deklaration die Form einer normalen Funktion oder Prozedur, nur daß der Prozedur- oder Funktions-Bezeichner ein qualifizierter Methodenbezeichner ist.

Für Konstruktoren und Destruktoren hat die definierende Deklaration die Form einer Prozedurdeklaration, nur daß das  reservierte Wort procedure durch das reservierte Wort constructor oder destructor ersetzt ist.

Die definierende Deklaration einer Methode darf (optional) die Liste der formalen Parameter des Methodenkopfes im Objekttyp wiederholen. Die definierende Deklaration muß exakt in Reihenfolge, Typ, Name der Parameter und Typen der Funktionswerte (falls vorhanden) übereinstimmen.

Parameter Self

In der definierenden Deklaration einer Methode ist immer ein impliziter Parameter Self vorhanden, der einem formalen Parameter des jeweiligen Objekttyps entspricht.

Innerhalb des Methodenblocks repräsentiert Self die Instanz deren Methodenkomponente die Methode aktivieren soll. Deshalb wirken sich alle Veränderungen der Felder von Self in der jeweiligen Instanz aus.


Beispiel

{ Hier ist ein Beispiel für eine Deklaration einer Methode }

procedure TRectangle.Intersect(var R: TRectangle);

begin

  if A.X < R.A.X then A.X := R.A.X;

  if A.Y < R.A.Y then A.Y := R.A.Y;

  if B.X > R.B.X then B.X := R.B.X;

  if B.Y > R.B.Y then B.Y := R.B.Y;

  if (A.X >= B.X) or (A.Y >= B.Y) then Init(0, 0, 0, 0);

end;

procedure TField.Display;

begin

  GotoXY(X, Y);

  Write(Name^, ' ', GetStr);

end;

function TNumField.PutStr(S: String): Boolean;

var

  E: Integer;

begin

  Val(S, Value, E);

  PutStr := (E = 0) and (Value >= Min) and (Value <= Max);

end;


Siehe auch

Konstruktoren und Destruktoren

Methoden

Objekt-Typen


Konstruktoren und Destruktoren

Siehe auch	Beispiel

Konstruktoren und Destruktoren sind spezielle Methoden, die die Erzeugung und Löschung von Objekten zur Aufgabe haben.

Eine Klasse kann keinen, einen oder mehrere Konstruktoren und Destruktoren für die Objekte des Klassentyps haben. Jeder ist als Bestandteil der Klasse definiert, wie auch die normalen Prozeduren und Funktionen, nur das die reservierten Wörter constructor und destructor am Anfang jeder Deklaration an Stelle von procedure und function stehen. Wie andere Methoden auch können Konstruktoren und Destruktoren vererbt werden.

Konstruktoren

Konstruktoren werden benutzt, um neue Objekte zu erzeugen und zu initialisieren. Normalerweise wird die Initialisierung mit als Parameter übergebenen Werten ausgeführt.

Im Gegensatz zu einer normalen Methode, die von einer Objektinstanz aktiviert werden muß, kann ein Konstruktor über eine Klassenrferenz oder eine Objektreferenz aktiviert werden.

Um ein neues Objekt zu erzeugen, muß der Konstruktor über eine Klassenreferenz aktiviert werden. Wenn ein Konstruktor über eine Klassenreferenz aktiviert wird geschieht folgendes:

Speicherplatz für das neue Objekt wird auf dem Heap allokiert.

Der allokierte Speicherbereich wird gelöscht. Alle ordinalen Werte werden auf Null, alle Zeiger und klassenwertigen Felder werden auf nil und alle String-Felder werden auf leer gesetzt.

Die benutzerdefinierten Aktionen des Konstruktors werden ausgeführt.

Eine Referenz auf den neu allokierten und initialisierten Speicherbereich wird vom Konstruktor zurückgegeben. Der Typ dieser Referenz ist der gleiche wie der Klassentyp im Konstruktoraufruf.

Wenn Sie einen Konstruktor über eine Objektreferenz aufrufen, so wird kein neues Objekt allokiert und gelöscht, der Konstruktoraufruf gibt auch keine Objektreferenz zurück. Der Konstruktor operiert auf der spezifizierten Objektreferenz und führt nur die benutzerdefinierten Anweisungen des Konstruktors aus. Ein Konstruktor wird typischerweise für eine Objektreferenz in Verbindung mit dem Schlüsselwort inherited aufgerufen, um einen ererbten Konstruktor aufzurufen.

Der erste Befehl eines Konstruktors ist häufig der Aufruf eines ererbten Konstruktors, um die ererbten Felder des Objektes zu initialisieren. Danach initialisiert der Konstruktor die neu eingeführten Felder der Klasse. Da der Speicherbereich nach der Allokation automatisch gelöscht wird haben alle Komponenten standardmäßig den Wert Null (ordinale Typen), nil (Zeiger- oder Klassentypen), leer (String-Typen) oder Nicht zugewiesen (der Varaiant-Typ). Eine Initialisierung eines Feldes ist also nur nötig, wenn der Wert nicht Null sein soll.

Wenn während der Ausführung eines Konstruktors, der auf einer Klassenreferenz aufgerufen wurde, eine Ausnahmebehandlung angestossen wird, so wird automatisch der entsprechende Destruktor aufgerufen, um das nicht vollständige Objekt zu löschen.

Wie andere Methoden auch, können Konstruktoren virtuell sein. Wenn sie durch einen Klassentyp-Bezeichner aufgerufen werden, was den Normalfall darstellt, so verhalten sich virtuelle Konstruktoren genau wie statische Konstruktoren. Wenn sie aber mit Objekt-Referenztypen kombiniert werden, erlauben virtuelle Konstruktoren die polymorphe Konstruktion von Objekten. Polymorph bedeutet, daß die auszuführende Funktion zum Zeitpunkt der Kompilation noch nicht festliegt.

Destruktoren

Destruktoren werden verwendet, um Objekte zu löschen. Wenn ein Destruktor aufgerufen wird, so werden die benutzerdefinierten Aktionen ausgeführt, dann wird der von dem Objekt allokierte Speicherbereich freigegeben. Die benutzerdefinierten Aktionen eines Destruktors sind normalerweise die Löschung von eingebetteten Objekten und das Freigeben von Ressourcen, die von dem Objekt belegt wurden.

Die letzte Aktion eines Konstruktors ist typischerweise der Aufruf des ererbten Destruktors, um alle ererbten Objektfelder zu löschen.

Obgleich es möglich ist mehrere Destruktoren für eine Klasse zu deklarieren, wird empfohlen, daß eine Klasse nur den ererbten Destroy-Destruktor überschreibt. Destroy ist ein parameterloser virtueller Destruktor, der in TObject deklariert wird. Da TObject die oberste Klasse in der Klassenhierarchie jeder Klasse ist, ist sichergestellt, daß der Destroy-Destruktor für jedes Objekt verfügbar ist.

Wenn während der Ausführung eines Konstruktors eine Ausnahmebehandlung aufgerufen wird, so wird der Destroy-Destruktor für das nicht vollendete Objekt aufgerufen. Destruktoren müssen also darauf vorbereitet sein, halbfertige Objekte zu zerstören. Da ein Konstruktor vor der Ausführung der benutzerdefinierten Aktionen alle Felder auf ihre Nullwerte setzt, ist sicher, daß alle Klassentypen oder Zeiger auf nil gesetzt sind. Ein Destruktor sollte deshalb immer auf nil-Werte abfragen, bevor Operationen auf Klassentypen oder zeigerwertigen Feldern ausgeführt werden.

Der Aufruf einer Free-Methode ist ein Weg, um auf nil zu prüfen, bevor Destroy für eine Objektreferenz aufgerufen wird. Dadurch, daß Sie Free anstelle von Destroy für alle klassenwertigen Felder aufrufen, wird der Destruktor automatisch darauf vorbereitet mit halbfertigen Objekten, die durch eine Ausnahmebehandlung während des Konstruktoraufrufes enstanden sind, fertig zu werden. Aus dem gleichen Grund werden direkte Aufrufe von Destroy nicht empfohlen.


Beispiel

Im folgenden Beispiel werden der Konstruktor und der Destruktor von TShape beschrieben.

type

  TShape = class(TGraphicControl)

  private

    FPen: TPen;

    FBrush: TBrush;

    procedure PenChanged(Sender: TObject);

    procedure BrushChanged(Sender: TObject);

  public

    constructor Create(Owner: TComponent); override;

    destructor Destroy; override;

    :

  end;

constructor TShape.Create(Owner: TComponent);

begin

  inherited Create(Owner);	{ Initialisiert ererbte Teile }

  Width := 65;	{ Ändert ererbte Eigenschaften }

  Height := 65;

  FPen := TPen.Create;	{ Initialisiert neue Felder }

  FPen.OnChange := PenChanged;

  FBrush := TBrush.Create;

  FBrush.OnChange := BrushChanged;

end;

destructor TShape.Destroy;

begin

  FBrush.Free;

  FPen.Free;

  inherited Destroy;

end;

procedure TObject.Free;

begin

  if Self <> nil then Destroy;

end;


Siehe auch

Instantiieren von Objekten

Methoden Deklarationen

Objekt-Typen


Indirekte Unit-Referenzen

Siehe auch	Beispiel

Der uses Absatz eines Modules muß nur die Namen der Units enthalten, die direkt von dem Modul verwendet werden.

Dennoch ist ein Modul häufig direkt von einem anderen abhängig. Um ein Modul zu kompilieren, muß der Kompiler in der Lage sein, alle Units von denen ein Modul direkt oder indirekt abhängt aufzufinden.

Wenn Sie an dem interface-Teil einer Unit Veränderungen vornehmen, so müssen Sie alle anderen Units rekompilieren, die diese geänderte Unit verwenden. Wenn Sie Compilieren|Alle erzeugen, verwenden, so übernimmt der Compiler das für Sie.

Wenn Veränderungen nur am implementation- oder initialization-Teil vorgenommen werden, so reicht es aus, die veränderte Unit erneut zu kompilieren.

Hinweis:	Für Benutzer von C und anderen Sprachen: Der uses Absatz von Object Pascal-Programmen enthält die "make"-Logik, die in anderen Sprachen üblicherweise in make- oder project-Dateien gespeichert werden. Mit dem uses-Absatz kann Object Pascal alle Abhängiggkeitsinformationen in dem Modul selbst darstellen, so daß die Wahrscheinlichkeit eines Fehlers verringert wird.

Der Object Pascal-Compiler erkennt, daß sich ein interface-Teil einer Unit verändert hat, da während des Kompilierens eine Versionsnummer der Unit berechnet wird.


Siehe auch

Unit

Uses


Beispiel

{ Das folgende ist ein Beispiel von Units die voneinander abhängig sind. Beachten Sie, daß Unit2 direkt von Unit1 abhängt und Prog ist unmittelbar abhängig von Unit2. }

program Prog;

uses Unit2;

const a = b;

begin

end.

unit Unit2;

interface

uses Unit1;

const b = c;

implementation

end.

unit Unit1;

interface

const c = 1;

implementation

const d = 2;

end.


Ringförmige Unit-Referenzen

Siehe auch	Beispiel

Ringförmige Unit-Referenzen treten auf, wenn Sie wechselseitig abhängige Units haben.

Ringförmige Unit-Referenzen treten auf, wenn Sie einen uses-Absatz in der Sektion implementation einer Unit verwenden, die inneren Details der Unit, die in uses referenziert wird enthält; Die referenzierte Unit ist privat und für das Programm oder die Unit in der es referenziert wird nicht zugreifbar.

Da Object Pascal vollständige interface Sektionen kompilieren kann, können zwei Units einander in dem uses Absatz ihrer implementation Sektion referenzieren. Der Kompiler akzeptiert eine Referenz auf eine teilkompilierte Einheit in der Sektion implementation einer anderen Unit, solange die interface Sektionen der Units nicht voneinander abhängen. Der Benutzer muß deshalb den strengen Pascal-Regeln für die Reihenfolge der Deklaration folgen.

Wenn die interface Sektionen voneinander abhängig sind, so erzeugt Object Pascal eine Fehlermeldung wegen ringförmiger Unit-Referenzen.

Wechselseitig abhängige Units können in speziellen Situationen nützlich sein, aber verwenden Sie sie mit Bedacht. Wenn Sie sie unnötigerweise verwenden, so machen sie Ihr Programm schwieriger in der Wartung und eher anfällig für Fehler.


Siehe auch

Unit

Uses


Beispiel

{ Das folgende Beispiel zeigt, wie zwei Units ein wechselseitiges "use" verwenden: }

program Circular;

{ Display text using WriteXY }

uses

  WinCrt, Display;

begin

  ClrScr;

  WriteXY(1, 1, 'Obere linke Ecke des Bildschirms');

  WriteXY(1000, 1000, 'Total außerhalb des Bildschirms');

  WriteXY(81 - Length('Zurück zu Realität'), 15, 'Zurück zur Realität');

end.

unit Display;

{ Enthält eine einfache Videoroutine }

interface

procedure WriteXY(X, Y: Integer; Message: String);

implementation

uses

  WinCrt, Error;

procedure WriteXY(X, Y: Integer; Message: String);

begin

  if (X in [1..80]) and (Y in [1..25] then

  begin

    GoToXY(X, Y);

    Write(Message);

  end

  else

    ShowError('Falsche WriteXY Koordinaten');

end;

end.

unit Error;

{ Enthält eine einfache Fehlermeldungsroutine }

interface

procedure ShowError(ErrMsg: String)

implementation

uses Display;

procedure ShowError(ErrMsg: String);

begin

  WriteXY(1, 25, 'Error: ' + ErrMsg);

end;

end.


Heap-Manager

Siehe auch

Windows unterstützt dynamische Speicherallokation auf zwei verschiedenen Heaps:

Der globale Heap

Der lokale Heap

Object Pascal beinhaltet einen Heap-Manager, der die folgenden Standardprozeduren beinhaltet:

New

Dispose

GetMem

FreeMem

Der Heap-Manager verwendet für alle Speicherallokationen den globalen Heap. Da der globale Heap eine systemweite Begrenzung auf 8192 Speicherblocks hat (dies ist weniger als für manche Anwendungen erforderlich sein kann), enthält der Heap-Manager einen segment sub-allocator Algorithmus, um die Leistung zu erhöhen und um die Allokation von mehr Blocks zu ermöglichen.

Damit sich die Segmentadressen der Blocks nicht verändern werden globale Blocks mit GlobalLock sofort nach der Allokation verriegelt. Die Verriegelung wird erst unmittelbar vor der Freigabe des Speicherbereichs gelöst.

Im Standard- und im 386 enhanced-Modus von Windows können Sie fixierte Blocks im physikalischen Speicher verschieben, um Platz für andere Speicheranforderungen zu schaffen. Der Object Pascal Heap-Manager bringt daher keinerlei Leistungsverlust.

Im Real-Modus von Windows muß ein fixierter Block an seiner Position im physikalischen Speicher fixiert bleiben. Dies verhindert, daß der Speichermanager von Windows die fixierten Blocks zur Allokation von anderen Blocks verschiebt.

Wenn Ihre Anwendung im Real-Modus laufen soll, prüfen Sie, ob Sie die memory-management Routinen von Windows verwenden können, um dynamische Speicherblocks zu allokieren.


Siehe auch

DLLs


Exit-Prozeduren

Siehe auch	Beispiel

Exit-Prozeduren ermöglichen Ihnen die Kontrolle über den Ablauf der Programmbeendigung. Dies ist nützlich, wenn Sie spezielle Aktionen ausführen möchten, bevor ein Programm beendet wird. Ein typisches Beispiel ist etwa das Aktualisieren und Schließen von Dateien.

Es gibt drei Arten der Anwendungsbeendigung:

Normale Beendigung

Beendigung durch Aufruf von Halt

Beendigung wegen eines Laufzeitfehlers (Object Pascal stellt eine Ausnahmebehandlung zur Behandlung von Laufzeitfehlern zur Verfügung, ohne daß die Anwendung abgebrochen wird.)

Um eine Exit-Prozedur zu installieren, verwenden Sie die Zeigervariable ExitProc.

Eine Exit-Prozedur nimmt keine Parameter an.

Wenn Sie sorgfältig implementiert wird, so wird eine Exit-Prozedur Teil einer Kette von Exit-Prozeduren, so daß es für Units und auch Programme möglich ist, Exit-Prozeduren zu installieren. Manche Prozeduren installieren eine Exit-Prozedur als Teil ihres Initialisierungs-Codes und verlassen sich dann darauf, daß diese spezielle Prozedur zum Löschen nach der Unit aufgerufen wird.

Die Prozeduren der Kette von Exit-Prozeduren werden in der umgekehrten Reihenfolge der Installation ausgeführt. Dies stellt sicher, daß der Exit-Code einer Unit nicht vor dem Exit-Code einer abhängigen Unit aufgerufen wird.

Um die Exit-Kette intakt zu halten, müssen Sie folgendes tun:

Speichern Sie den aktuellen Inhalt von ExitProc bevor Sie die Adresse auf Ihre eigene Exit-Prozedur setzen.

Reinstallieren Sie den gespeicherten Wert von ExitProc in der ersten Anweisung Ihrer Exit-Prozedur.

Die Beendigungsroutine in der Laufzeitbibliothek ruft solange Exit-Prozeduren auf, bis ExitProc den Wert nil hat.

Um Endlosschleifen zu vermeiden, wird ExitProc vor jedem Aufruf auf nil  gesetzt, so daß die nächste Exit-Prozedur nur aufgerufen wird, wenn die aktuelle Exit-Prozedur ExitProc eine Adresse zuweist. Wenn in einer Exit-Prozedur ein Fehler auftritt, so wird diese nicht wieder aufgerufen.

Eine Exit-Prozedur kann den Grund der Beendigung durch Prüfung der Integer-Variable ExitCode und der Zeigervariable ErrorAddr erkennen. ExitCode und ErrorAddr haben je nach Grund der Beendigung folgende Werte:

Normal	Laufzeit-

Variable	Beendigung	Halt	Fehler

ExitCode	Null	Wert übergeben an Halt	Fehler-Code

ErrorAddr	nil	nil	Adresse der fehlerhaften Anweisung

Die letze Exit-Prozedur (die von der Laufzeit Bibliothek installierte) schließt die Eingabe- und Ausgabedateien. Wenn ErrorAddr nicht den Wert nil hat, so wird eine Laufzeitfehler-Meldung ausgegeben.

Fehlermeldungen

Wenn Sie selbst Fehlermeldungen ausgeben möchten, installieren Sie eine Exit-Prozedur, die den Wert von ErrorAddr untersucht und eine Meldung ausgibt, wenn dieser nicht nil  ist. Sie müssen auch ErrorAddr vor der Rückkehr auf nil setzen, so daß der Fehler nicht in einer anderen Exit-Prozedur nochmals gemeldet wird.

Sobald die Laufzeit-Bibliothek alle Exit-Prozeduren aufgerufen hat, kehrt sie zu Windows zurück und gibt als Rückgabewert den Wert aus ExitCode zurück.


Siehe auch

DLLs

Ausnahmebehandlung


Beispiel

{Das folgende Beispiel demonstriert das Skelett einer Implementation einer Exit-Prozedur:}

program TestExit;

var

 ExitSave: Pointer;

procedure MyExit;

begin

  ExitProc := ExitSave;  { Always restore old vector first }

end;

begin

  ExitSave := ExitProc;

  ExitProc := @@MyExit;

end.


Verändern der Z-Order von Komponenten

Wenn ein Formular überlappende Komponenten enthält, so liegt die Ebene der als letzes hinzugefügten Komonente immer vor der Ebene der vorhergehenden Komponenten. Mit anderen Worten existiern überlappende Objekte eines Formulares in Schichten.

   Back   [image]  Front

Unter Umständen fügen Sie die Komponenten nicht in der Reihenfolge hinzu, in der diese erscheinen sollen. Es kann sein, daß Sie eine Komponente hinter eine andere verschieben möchten. Dafür müssen Sie die Position der sichtbaren Schicht verändern. Diese visuellen Schichten eines Formulares sind als z-Order bekannt, da diese Komponenten auf der z-Achse (Tiefe) des Layouts liegen. Dieses legt fest, was vor was dargestellt wird.

Dies ist sehr nützlich, wenn Sie Graphiken oder Bilder hinzufügen, die Sie im Hintergrund des Formulars anzeigen möchten.

Um die z-Order einer Komponente zu verändern,

1.	Wählen Sie die Komponente aus.

2.	Wählen Sie entweder Bearbeiten|Nach vorne bringen oder Bearbeiten|Nach hinten setzen, je nachdem in welche Richtung Sie die Komponente verschieben möchten.

Hinweis:	Fensterfähige und nicht fensterfähige Komponenten haben ihre eigene z-Order Logik. Sie können kein nicht Fensterfähige Kontrollelemente, wie zum Beispiel eine Label- oder eine Bild-Komponente in die z-Order eines Fensterfähigen Kontrollelementes mit einbeziehen.


Direkter Speicherzugriff

Object Pascal implementiert drei vorgegebene Arrays, die für den direkten Zugriff auf den Speicher verwendet werden.

Mem

MemW

MemL

Jede Komponente von Mem ist ein Byte, jede Komponente von MemW ist ein Wort und jede Komponente von MemL ist ein Longint.

Die Mem-Arrays verwenden für Indizes eine besondere Syntax:

Zwei Ausdrücke vom Ganzzahl-Typ Wort, getrennt durch einen Doppelpunkt, geben die Segmentbasis und den Offset der Speicheradresse an, auf die zugegriffen wird.

Hier zwei Beispiele:

Mem[Seg0040:$0049] := 7;     {speichert den Wert 7 in dem Byte bei $0040:$0049}

Data := MemW[Seg(V):Ofs(V)]; {verschiebt den Wort-Wert aus den ersten 2 Bytes der Varaiable V in die Variable Data}


Aufrufskonventionen

Siehe auch

Object Pascal bietet vier Direktiven, mit denen Sie die Aufrufskonventionen festlegen können, die für die Übergabe von Parametern and Prozeduren und Funktionen verwendet werden sollen. Die Standard-Aufrufskonvention ist immer register.

Die Aufrufskonventionen unterscheiden sich in drei Bereichen:

Reihenfolge der Parameterübergabe

Zuständigkeit für das Löschen von Parametern aus dem Stack ("Cleanup")

Verwendung von Registern zur Parameterübergabe

Die Konventionen register und pascal übergeben Parameter von links nach rechts, das heißt, der am weitesten links stehende Parameter wird als erstes berechnet und übergeben, der am weitesten rechts stehende als letztes. Die Konventionen cdecl und stdcall übergeben Parameter von rechts nach links. Bei allen Konventionen, außer cdecl, löscht die Prozedur oder Funktion beim Zurückkehren die Parameter aus dem Stack. Bei der Konvention cdecl muß der Aufrufer die Parameter aus dem Stack entfernen, wenn der Aufruf zurückkehrt. Die Konvention register verwendet bis zu drei CPU-Register zur Parameterübergabe, während die anderen Konventionen immer alle Parameter an den Stack  übergeben.

In folgender Tabelle sind die Aufrufskonventionen zusammengefaßt.

Direktive	Reihenfolge	Cleanup	Register
register	Links-nach-rechts	Funktion	Ja
pascal	Links-nach-rechts	Funktion	Nein
cdecl	Rechts-nach-links	Aufrufer	Nein
stdcall	Rechts-nach-links	Funktion	Nein

Die Konvention register ist die deutlich effektivste, da sie oftmals das Erstellen eines Stack-Rahmens umgeht. Die Konventionen pascal und cdecl sind besonders für den Aufruf von Routinen in Dynamic-Link-Libraries, die in C, C++ oder anderen Sprachen geschrieben wurden, geeignet. Die Konvention stdcall wird für den Aufruf von Routinen der Windows API verwendet.


Siehe auch

Prozeduren

Funktionen


Rangfolge der Operatoren

Siehe auch

Operatoren sind Symbole oder reservierte Wörter, die anzeigen, daß einige Operationen auf ein oder meherere Datenstücke angewandt werden.

Die Rangfolge der Object Pascal-Operatoren ist:

Operatoren	Priorität	Kategorie

@ not	Eins (hoch)	Unärer Operator

* / div mod as	Zwei	Multiplikative und typum-

and shl shr 	wandelnde Operatoren

+ - or xor	Drei	Additive Operatoren

= <> < >	Vier (niedrig)	Relationale, Mengenzugehörigkeits-,

<= >= in is 	und Typvergleichsoperatoren

Auswertungsregeln

1.	Ein Operand zwischen zwei Operatoren unterschiedlicher Priorität wird an den Operator höherer Priorität gebunden.

2.	Ein Operand zwischen Operatoren gleicher Priorität wird an den Operator gebunden, der links von ihm steht.

3.	Ausdrücke in Klammern werden zuerst ausgewertet, und der gesamte Ausdruck wird als ein einzelner Operand behandelt.


Siehe auch

@-Operator

Zuweisungsoperator

Binäre arithmetische Operatoren

Bitweise Operatoren

Boolesche Operatoren

Character-Pointer-Operatoren

Relationale Operatoren

Mengenoperatoren

String-Operatoren

Unäre arithmetische Operatoren

Variante Operatoren


Binäre arithmetische Operatoren

Siehe auch	Operatoren

Binäre arithmetische Operatoren führen arithmetische Operationen auf zwei Operanden aus.

Es gibt folgende binäre arithmetische Operatoren:

Operator	Operation	Operanden	Ergebnistyp

+	Addition 	Integer	Integer

Real	Real

-	Subtraktion	Integer	Integer

Real	Real

*	Multiplikation	Integer	Integer

Real	Real

/	Division	Integer	Real

Real	Real

div	Integer Division	Integer	Integer

mod	Modulo	Integer	Integer

Jeder Operand, dessen Typ ein Teilbereich eines ordinalen Typs ist, wird behandelt, als sei er selbst von diesem ordinalen Typ.

Falls die Operanden eines +, -, *, div, oder mod -Operators Integer-Typen sind, ist der Ergebnistyp der allgemeinere Typ der beiden Operanden.

Falls beide Operanden eines +, -, or * -Operators Real-Typen sind, ist der Ergebnistyp Extended.

Falls der Operand des Operators für Vorzeichengleichheit oder für Vorzeichenwechsel ein Integer ist, ist das Ergebnis vom selben Integer-Typ. Falls der Operator von einem Real-Typ ist, ist das Ergebnis vom Typ Extended.

Der Wert von  X/Y  ist immer vom Typ Extended, unabhängig vom Operandentyp. Falls Y gleich Null ist, wird ein Laufzeitfehler ausgegeben. Sie können diesen Laufzeitfehler durch Verwendung von Exceptions weiterverarbeiten.

Der Wert  I div J  entspricht dem mathematischen Quotienten I / J, der auf einen Wert vom Typ Integer in Richtung von Null gerundet wird. Sie können diesen Laufzeitfehler durch Verwendung von Exceptions weiterverarbeiten.

Der Operator mod berechnet den Rest der Division beider Operanden:

  I mod J = I - (I div J) * J

Das Vorzeichen des Ergebnissen von mod entspricht demjenigen von I. Falls J gleich Null ist, tritt ein Fehler auf.

Hinweis:	Die Operatoren +, -, und * können auch als Mengenoperatoren, Character-Pointer-Operatorens oder unäre Operatoren verwendet werden. Der Operator + ist auch der Stringoperator.


Siehe auch

Typen


Is-Operator

Siehe auch

Der is Operator wird benutzt um eine dynamische Typüberprüfung zu ermöglichen. Benutzen Sie den is Operator um zu überprüfen ob der aktuelle Typ einer Objektreferenz zu einer bestimmten Klassegehört. Die Syntax des is Operators ist folgende

ObjectRef is ClassRef

wobei ObjectRef eine Objektrefrenz und ClassRef eine Klassenreferenz ist. Der is Operator liefert einen Booleab-Wet zurück. Das Ergebnis ist True wenn ObjectRef eine Instanz der Klasse benannt von ClassRef ist oder eine Instanz oder Klasse abgeleitet von der KLasse ClassRef. Ansonsten ist das Ergebnis False. Wenn ObjectRef nil ist, ist das Ergebnis immer False. Wenn die deklarierten Typen von ObjectRef und ClassRef als nicht verwandt bekannt sind wird der Compiler einen Typmismatch Fehler ausgeben.

Der is Operator wird häufig im Zusammenhang mit der if-Anweisung benutzt um eine überwachte Typumwandlung auszuführen. Zum Beispiel,

if ActiveControl is TEdit then TEdit(ActiveControl).SelectAll;

Wenn der is Test True ist,ist es sicher eine Typumwandlung durchzuführen.

Wenn man den is Operator mit anderen boolschen Ausdrücken mixt muß der is-Test in Klammern gestzt werden:

if (Sender is TButton) and (TButton(Sender).Tag <> 0) then ...;


Siehe auch

Konditionelle Anweisungen


As-Operator

Siehe auch

Der as Operator wird benutzt um Typumwandlungen zu überprüfen. Die Syntax ist folgende

ObjectRef as ClassRef

wobei ObjectRef eine Objektrefrenz und ClassRef eine Klassenreferenz ist. Der as Operator liefert einen Booleab-Wet zurück. Das Ergebnis ist True wenn ObjectRef eine Instanz der Klasse benannt von ClassRef ist oder eine Instanz oder Klasse abgeleitet von der KLasse ClassRef. Ansonsten ist das Ergebnis False. Wenn ObjectRef nil ist, ist das Ergebnis immer False. Wenn die deklarierten Typen von ObjectRef und ClassRef als nicht verwandt bekannt sind wird der Compiler einen Typmismatch Fehler ausgeben.

Der as Operator wird häufig im Zusammenhang mit der with-Anweisung benutzt um eine überwachte Typumwandlung auszuführen. Zum Beispiel,

with Sender as TButton do

begin

  Caption := '&Ok';

  OnClick := OkClick;

end;

Wird der as-Operator in einer Variablenreferenz benutzt muß die as-Typenumwandlung in Klammern eingeschlossen sein:

(Sender as TButton).Caption := '&Ok';


Siehe auch

Variable Typumwandlung

With-Anweisungen


Unäre arithmetische Operatoren

Operatoren

Unäre arithmetische Operatoren bezeichnen das Vorzeichen eines Operanden.

Es gibt folgende unäre arithmetische Operatoren:

Operator	Operation	Operanden	Ergebnistyp

+	Identität	Integer	Integer

Real	Real

-	Negation	Integer	Integer

Real	Real

Hinweis:	Operanden, die Teilbereiche ordinaler Typen darstellen, werden auf dieselbe Weise wie der ursprüngliche Ordinaltyp behandelt.

Falls der Operand von + oder - vom Typ Real ist, ist der Ergebnistyp Extended.

Hinweis:	Die Operatoren + und - können auch als Mengenoperatoren, Character-Pointer-Operatoren oder binäre Operatoren verwendet werden. Der Operator + ist auch der Stringoperator.


Bitweise Operatoren

Operators

Die bitweisen Operatoren verändern die Bit-Werte von Integer-Typen.

Es gibt folgende bitweise Operatoren:

Operator	Operation	Operanden	Ergebnistyp

not	Bitweise Negation	Integer	Integer

and	Bitweises and	Integer	Integer

or	Bitweises or	Integer	Integer

xor	Bitweises xor	Integer	Integer

shl	Bitweises Linksschieben	Integer	Integer

shr	Bitweises Rechtsschieben	Integer	Integer

not invertiert Bit-Werte, z.B. wenn ein Bit den Wert 1 hat, ändert not diesen auf Null.

Der Operator not ist ein unärer Operator. Wenn der Operand von not einen Integer-Typ hat, dann ist auch das Ergebnis vom selben Format.

Die bitweisen Operatoren and, or oder xor führen boolesche Operationen auf einander entsprechenden Bits durch.

Wenn beide Operanden der Operatoren and, or oder xor einen Integer-Typ haben, dann hat das Ergebnis das allgemeinere Format der beiden Operanden.

Die Operationen  I shl J  und  I shr J  verschieben den Wert von I um J Bitpositionen nach links bzw. nach rechts. Der Typ des Ergebnisses ist der Typ von I. Das Vorzeichenbit wird durch shr vervielfacht.

not, and, or, und xor sind auch Boolesche Operatoren.


Boolesche Operatoren

Siehe auch	Operatoren

Boolesche Operatoren verwenden Boolesche Logik zur Auswertung von Ausdrücken.

Es gibt folgende boolesche Operatoren:

Operator	Operation	Operanden	Ergebnistyp

not	Negation	Boolean	Boolean

and	logisches and	Boolean	Boolean

or	logisches or	Boolean	Boolean

xor	logisches xor	Boolean	Boolean

not invertiert boolesche Werte, z.B. gilt: not True ist False. Der Operator not ist ein unärer Operator.

and ergibt True, wenn beide Operanden zu True ausgewertet werden.

or ergibt True, wenn mindestens ein Operand True ist.

xor ergibt True, wenn genau ein Operand True ist. Sind beide Operanden True oder beide False, dann ergibt sich False.

Die Operatoren and und or arbeiten auf booleschen Werten und Object Pascal unterstützt zwei verschiedene Modelle zur Codeerzeugung für diese Operatoren.

Vollständige Auswertung

Kurzschlußauswertung

Das Auswertungsmodell wird über den Compiler-Befehl $B bestimmt. Im voreingestellten Zustand {$B-} erzeugt der Compiler Code für die Kurzschlußauswertung. Im Zustand {$B+} erzeugt der Compiler Code für die vollständige Auswertung.

not, and , or und xor sind auch bitweise Operatoren.


Siehe auch

Boolesche Ausdrücke

Boolesche Typen


String-Operator

Siehe auch	Operatoren

Der Operator + verkettet zwei Strings.

Operator	Operation	Operanden	Ergebnistyp

+	Verkettung	String, Char	String

oder packed String

Das Ergebnis ist mit jedem String-Typ kompatibel (allerdings nicht mit den Typen Char und packed String).

Wenn die Operanden kurz sind und das Ergebnis die Länge von 255 Zeichen überschreitet, wird das Ergebnis nach dem 255. Zeichen abgeschnitten. Wenn einer der Operanden lang ist, ist auch das Ergebnis lang.

Hinweis:	Der Operator + kann auch als Mengenoperator, unärer Operator, Character-Pointer-Operatoren oder binäre Operatoren verwendet werden.


Siehe auch

Relationale Operatoren


Character-Pointer-Operatoren

Operatoren

Die Operatoren plus ( + ) und minus ( - ) können verwendet werden, um einen Char-Zeiger-Wert zu inkrementieren bzw. zu dekrementieren und der Operator minus ( - ) kann den Abstand (Differenz) zwischen zwei Char-Zeiger berechnen.

Der Operator minus ( - ) kann zur Berechnung des Abstands (Differenz) zwischen den Offset-Teilen zweier Char-Zeiger verwendet werden.

Folgende Konstrukte sind erlaubt, vorausgesetzt, P und Q sind Werte vom Typ PChar und I ist ein Wert vom Typ Integer:

Konstrukt	Ergebnis

P + I	Addiert I zu P

I + P	Addiert I zu P

P - I	Subtrahiert I von P

P - Q	Subtrahiert Q von P

Die Operationen P + I und I + P addieren I zur durch P bezeichneten Adresse und liefern einen Zeiger, der auf die Position I Zeichen hinter P zeigt.

Die Operation P - I subtrahiert I von der durch P bezeichneten Adresse und resultiert in einem Zeiger, der auf die Position I Zeichen vor P zeigt.

Die Operation P - Q berechnet den Abstand zwischen Q (der niedrigeren Adresse) und P (der höheren Adresse). Sie resultiert in einem Wert vom Typ Integer, der die Anzahl von Zeichen zwischen Q und P angibt.

Diese Operation setzt voraus, daß P und Q auf dasselbe Char-Array zeigen. Wenn die beiden Char-Zeiger auf verschiedene Char-Arrays zeigen, ist das Ergebnis undefiniert.


Mengen-Operatoren

Operatoren

Mengenoperatoren werden eingesetzt, um die Vereinigung, Differenz oder Schnittmenge zweier Mengen zu bestimmen, oder um auf Mengenzugehörigkeit zu testen.

Es gibt folgende Mengenoperationen:

Operator	Operation	Operanden

+	Vereinigung	kompatible Mengen

-	Differenz	kompatible Mengen

*	Durchschnitt	kompatible Mengen

in	Element von	linker Operand: jeder ordinale Typ T

rechter Operand: Menge, deren Basistyp mit T kompatibel ist

Die Resultate der Operationen ergeben sich aus den Gesetzen der Mengenlehre:

Ein Ordinalwert C ist nur dann in A  +  B enthalten, wenn er in A oder B enthalten ist.

Ein Ordinalwert C ist nur dann in A  -  B enthalten, wenn er in A, aber nicht in B enthalten ist.

Ein Ordinalwert C ist nur dann in A  *  B enthalten, wenn er sowohl in A als auch in B enthalten ist.

Wenn A als Element des Ergebnisses einer Mengen-Operation der kleinste Ordinalwert innerhalb dieser Menge ist und B der größte, dann ist set of A..B der Typ des Ergebnisses. Die Ergebnisse der Operatoren + , - und * sind Mengen, das Ergebnis des Operators in ist eine Boolean.


Relationale Operatoren

Siehe auch	Operatoren

Relationale Operatoren vergleichen Operanden und geben abhängig vom Ergebnis einen booleschen Wert zurück.

Operator 	Operation	Ergebnistyp	Operanden

=	gleich	Boolean	kompatible einfache, Zeiger-, Mengen-, String-, gepackte String-, oder variante Typen

<>	ungleich	Boolean	kompatible einfache, Zeiger-, Mengen-, String-, gepackte String-, oder variante Typen

<	kleiner als	Boolean	kompatible einfache, String-, gepackte String-, PChar- oder variante Typen

>	größer als	Boolean	kompatible einfache, String-, gepackte String-, PChar- oder variante Typen

<=	kleiner od. gleich	Boolean	kompatible einfache, String-, gepackte String-, PChar- oder variante Typen

>=	größer od. gleich	Boolean	kompatible einfache, String-, gepackte String-, PChar- oder variante Typen

<=	Teilmenge von	Boolean	kompatible Mengen-Typen

>=	Obermenge von	Boolean	kompatible Mengen-Typen


Siehe auch

Boolesche Ausdrücke

Boolesche Operatoren

Typkompatibilität


Der Adreß-Operator @: Zeiger-Operationen

Siehe auch	Beispiel	Operatoren

Der @-Operator wird als Adressfaktor verwendet, um die Adresse einer Variablen, einer Prozedur, einer Funktion oder einer Methode zu berechnen.

Der @-Operator gibt die Adresse seines Operanden als Ergebnis zurück, d.h. er erzeugt einen Zeigerwert Zeiger, der auf den Operanden zeigt.

Sie können mit der @-Operator einen Zeiger auf eine Variable erzeugen.

@ ist ein unärer Operator.

Bei der Verwendung des @-Operators in Verbindung mit einer prozeduralen Variable sind spezielle Regeln zu beachten. Der Typ des Werts ist derselbe wie der Typ von nil, kann also jeder Zeigervariable zugewiesen werden.

@ mit	Ergibt einen Zeiger auf

Variable	die Variable.

Wertparameter	die Stelle des Stacks, die den aktuellen Wert enthält.

variablem Parameter	den aktuellen Parameter. Der Wert des Zeigertyps wird durch den Compiler-Befehl $T bestimmt.

Prozedur oder Funktion	den Aufsetzpunkt der Prozedur oder Funktion.

Methode	den Aufsetzpunkt der Methode.

Wenn der @-Operator auf eine variable Referenz angewandt wird, wird der Typ des resultierenden Zeigerwertes durch den Compiler-Befehl {$T} bestimmt.

Der Typ des resultierenden Zeigers auf den Aufsetzpunkt einer Routine ist immer ein Zeiger.

Die einzige Verwendung eines Mehoden- oder Prozedurzeigers liegt darin, ihn an eine Assembler-Routine zu übergeben.

Vorzugsweise wird eine Methode mit einem qualifizierten Methodenbezeichner referenziert.


Beispiel

{Das folgende Beispiel verändert eine Kopie des Parameters.}

procedure ValueEx (X :Integer);

var

  ptr := ^integer;

begin

  ptr := @X;

  writeln(Ptr^);

  Ptr^ := 15;

end;

var

  Fred : integer;

begin

  Fred := 10;

  ValueEx (Fred);

  Writeln (Fred);    {10}

end.

{Das folgende Beispiel verändert den aktuellen Parameter.}

procedure VarEx(var Y : integer);

var Ptr = ^integer;

begin

  Ptr := @Y;

  writeln (Ptr^);

  Ptr^ := 15;

end;

var Fred : integer;

begin

  Fred := 10;

  VarEx (Fred);

  writeln (Fred);    {15}

end.


Siehe auch

Prozedurale Werte

Wertparameter

Variable Parameter


Zuweisungsoperator ( :=)
Zuweisungsoperator

Siehe auch	Beispiel	Operatoren

Syntax

Beschreibung

Der Zuweisungsoperator  :=  übergibt den Wert eines Ausdrucks (auf der rechten Seite) an eine Variable gleichen Typs (auf der linken Seite).


Beispiel

X    := Y;

Done := (I > 0) and (I < 100)

A[I] := A[I] + 1;


Siehe auch

Zuweisungskompatibilität

Ausdruck

Anweisung

Variable


Variant-Operatoren

Siehe auch	Operatoren

Die Operatoren +, –, *, /, div, mod, shl, shr, and, or, xor und not unterstützen Operanden vom Typ Variant. Wenn bei binären Operatoren ein Operand vom Typ Variant ist, wird der andere Operand automatisch in den Zyp Variant konvertiert.


Siehe auch

Variante Types

Variante Ausdrücke


Reservierte Wörter

Siehe auch

Reservierte Wörter haben innerhalb der Programmiersprache von Object Pascal eine feste Bedeutung. Sie können nicht umdefiniert werden.

Object Pascal macht bei reservierten Wörtern keinen Unterschied zwischen Groß- und Kleinschreibung. Das gleiche gilt auch für beliebige Kombinationen reservierter Wörter.

Sowohl in Handbüchern als auch in diesem Hilfesystem erscheinen reservierte Wörter fett.

Es folgt eine alphabetische Liste der reservierten Wörter von Object Pascal.

and	exports	library	shl
array	file	mod	shr
as	finalization	nil	string
asm	finally	not	then
begin	for	object	threadvar
case	function	of	to
class	goto	on	try
const	if	or	type
constructor	implementation	packed	unit
destructor	in	procedure	until
div	inherited	program	uses
do	initialization	property	var
downto	inline	raise	while
else	interface	record	with
end	is	repeat	xor
except	label	set


Siehe auch

Standard-Anweisungen


Standard-Anweisungen

Siehe auch

Die Standard-Anweisungen besitzen eine vordefinierte Bedeutung. Diese Begriffe können jedoch neu definiert werden, wozu aber nicht geraten wird. Anweisungen werden nur in solchen Zusammenhängen verwendet, in denen benutzerdefinierte Bezeichner nicht auftreten dürfen.

Sowohl in Handbüchern als auch in diesem Hilfesystem erscheinen Standard-Anweisungen fett.

Object Pascal macht bei Standard-Anweisungen keinen Unterschied zwischen Groß- und Kleinschreibung. Das gleiche gilt auch für beliebige Kombinationen der Standard-Anweisungen.

Es folgt eine alphabetische Liste der Standard-Anweisungen aus Object Pascal.

absolute

abstract

assembler

at

automated

cdecl

default

dispid

dynamic

external

forward

index

message

name

nodefault

override

pascal

private

protected

public

published

read

register

resident

stdcall

stored

virtual

write

Die Anweisungen private, protected, public, published und automated fungieren innerhalb der Klassentyp-Deklarationen als  reservierte Wörter, werden aber ansonsten wie Anweisungen behandelt.


Siehe auch

Reservierte Wörter


Absolute (Standard-Anweisung)
Absolute

Beispiel	Standard-Anweisungen

Syntax

absolute address

Beschreibung

Die Standard-Anweisung absolute deklariert eine Variable, die sich an einer bestimmten Speicheradresse befindet.

Diese Anweisung:

Weist der Variablen eine bestimmte Adresse direkt zu.

Deklariert die Variable so, daß sie sich an der gleichen Speicheradresse wie eine Variable befindet.

Über die erste Form wird die Adresse der Variablen direkt angegeben.

Die zweite Form deklariert eine neue Variable oberhalb einer vorhandenen Variablen (an der gleichen Adresse).

In der Bezeichnerliste für Variablendeklarationen darf nur ein Bezeichner angegeben werden, wenn eine absolute-Klausel enthalten ist.


Beispiel

var

  Str: ShortString;

  StrLen: Byte absolute Str;


Abstract (Standard-Anweisung)
Abstract

Beispiel	Standard-Anweisungen

Beschreibung

Über die Anweisung abstract wird in einer Objektdefinition angegeben, daß in diesem Objekt keine virtuelle oder dynamische Methode deklariert ist. Deren Definitionen werden dann für die nachfolgenden Klassen abstrahiert. Eine abstrakte Methode definiert in Wirklichkeit ein Interface, jedoch nicht die darunterliegende Operation.

Sie können keine Methode als abstrakt deklarieren, wenn diese nicht zuvor als virtual oder dynamic deklariert wurde. Diese Methode darf auch nicht aufgerufen werden, ohne überschrieben worden zu sein. Eine abstrakte Methode wird genauso überschrieben wie eine normale virtuelle oder dynamische Methode, außer daß in der Implementierung der überschreibenden Methode keine inherited-Methode aufgerufen werden kann.

Bei dem Versuch, eine abstrakte Methode aufzurufen, die nicht überschrieben wurde, wird die Prozedur Abstract aus der Laufzeitbibliothek aufgerufen und das Programm mit einem Laufzeitfehler beendet.


Beispiel

type

  TMyObject = class

    procedure Something; virtual; abstract;

  end;


Array (Reserviertes Wort)
Array

Siehe auch	Beispiel

Syntax

array [index-type] of element-type

Beschreibung

Das reservierte Wort array definiert einen Array-Typ.

Es ist möglich, mehrere Indextypen anzugeben, wenn sie durch Kommata voneinander getrennt werden.

Als Elementtyp ist jeder Typ zulässig, der Indextyp muß jedoch ein ordinaler Typ sein.


Beispiel

type

  IntList  = array[1..100]     of Integer;

  CharData = array['A'..'Z']   of Byte;

  Matrix   = array[0..9, 0..9] of real;


Siehe auch

Array type

Array-type constants

Indexes


Asm (Reserviertes Wort)
Asm

Siehe auch	Reservierte Wörter

Syntax

  asm

    AssemblerStmt <Separator AssemblerStmt>

  end

Dabei ist

AssemblerStmt eine Assembleranweisung.

Der Separator ein Strichpunkt, eine neue Zeile oder ein Pascal-Kommentar.

Beschreibung

Das reservierte Wort asm greift auf den integrierten Assembler zu.

Mehrfache Assembleranweisungen in einer Zeile werden durch Strichpunkte getrennt. Für Assembleranweisungen in unterschiedlichen Zeilen ist kein Strichpunkt erforderlich.

In einer asm-Anweisung bedeutet ein Strichpunkt nicht, daß der Rest der Zeile Kommentar ist. Kommentare müssen im Pascal-Stil mit { und } oder (* und *) gekennzeichnet werden.

Die Verwendung von Registern

Für die Anwendung von Registern in einer asm-Anweisung gelten dieselben Regeln wie für eine Externe Prozedur oder -Funktion.

Eine asm-Anweisung muß folgende Register sichern:

EDI	ESI

EBP	EBX

Eine asm-Anweisung kann folgende Register ändern:

EAX	EDX	ECX

Beim Eintritt in die asm-Anweisung kennt der integrierte Assembler nur die Register EDI, ESI, EBP und EBX.


Siehe auch

Assembler directive

Comments

External


Assembler (Prozedur-Anweisung)
Assembler

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Mit dem Standard-Anweisung assembler können Sie ohne eine begin...end Anweisung vollständige Prozeduren und Funktionen schreiben.

Die assembler-Anweisung veranlaßt den Compiler, die Code-Generierung folgendermaßen zu optimieren:

Wertparameter: Der Compiler generiert keinen Code, der Wertparameter in lokale Variablen kopiert. Dies wirkt sich auf alle Wertparameter vom Typ String sowie die Werteparameter aus, deren Größe nicht 1, 2 oder 4 Bytes beträgt.

Solche Parameter müssen innerhalb einer Prozedur oder Funktion als var-Parameter behandelt werden.

Funktionsergebnis-Variable: Der Compiler weist keine Funktionsergebnis-Variable zu; eine Referenz auf das Symbol @Result ist ein Fehler.

String-Funktionen bilden eine Ausnahme bei Funktionsergebnis-Optimierungen. Sie haben immer einen @Result-Zeiger, der vom Aufrufer zugewiesen wird.

Stack Frame: Der Compiler generiert keinen Stack Frame für solche Prozeduren und Funktionen, die weder Parameter noch lokale Variablen besitzen.

Der automatisch erzeugte Eintritts- und Austrittscode einer Assemblerprozedur oder -funktion sieht folgendermaßen aus:

  PUSH   BP          ;Present if Locals <> 0 or Params <> 0

  MOV    BP, SP      ;Present if Locals <> 0 or Params <> 0

  SUB    SP, Locals  ;Present if Locals <> 0

    .

    .

    .

  MOV    SP, BP      ;Present if Locals <> 0

  POP    BP          ;Present if Locals <> 0 or Params <> 0

  RET    Params      ;Always present

Wenn sowohl Locals als auch Params gleich null sind, gibt es keinen Eintrittscode. Der Austritscode besteht dann nur aus einer RET-Anweisung.

Funktionen, in denen assembler verwendet wird, müssen ihre Ergebnisse folgendermaßen zurückgeben:

Funktionstyp	Rückgabewerte

Ordinal	AL (8-Bit-Werte)
AX (16-Bit-Werte)
DX:AX (32-Bit-Werte)

Real	ST(0) im Register-Stack des Koprozessors

Zeiger	EAX

Short String	Temporäre Adresse, auf die über @Result verwiesen wird


Siehe auch

Asm


Automated (Standard-Anweisung)
Automated

Siehe auch	Standard-Anweisungen

Die Regeln für die Sichtbarkeit automatisierter Komponenten sind mit denen öffentlicher Komponenten identisch. Der einzige Unterschied zwischen automatisierten und öffentlichen Komponenten besteht darin, daß die Automatisierungstyp-Information für Methoden und Eigenschaften erzeugt wird, die in einem automatisierten Abschnitt deklariert sind. Diese Automatisierungstyp-Information ermöglicht die Erstellung eines OLE-Automatisierungs-Servers.

Hinweis:	Automatisierte Abschnitte werden normalerweise nur in Klassen verwendet, die von der TAutoObject-Klasse, welche in der OleAuto-Einheit definiert ist, abgeleitet sind.

Die folgenden Restriktionen wirken sich auf Methoden und Eigenschaften aus, die in einem automatisierten Abschnitt deklariert sind:

Für eine Methode müssen alle Typen von Methodenparametern und Funktionsergebnissen (falls vorhanden) automatisierbar sein. Genauso müssen für eine Eigenschaft die Eigenschaftstypen und die Datenfeldeigenschaftsparameter automatisierbar sein.

Die automatisierbaren Typen sind:

Byte, Currency, Double, Integer, Single, Smallint, string, TDateTime, Variant, WordBool.

Methoden und Eigenschaften, die nichtautomatisierbare Typen in einem automatisierten Abschnitt verwenden, erzeugen einen Fehler.

Methodendeklarationen müssen die Register-Auffrufkonvention verwenden (standardmäßig).

Methoden können virtuell, aber nicht dynamisch sein.

Eigenschaftsdeklarationen können nur Zugriffangaben enthalten (read und write). Es sind keine anderen Angaben (index, stored, default, nodefault) zugelassen.

Eigenschaftszugriffsangaben müssen einen Methodenbezeichner auflisten. Feldbezeichner sind nicht zugelassen.

Eigenschaftszugriffsmethoden müssen die Register-Auffrufkonvention verwenden.

Eigenschaftsüberschreiber (Eigenschaftsdeklarierer, die den Eigenschaftstyp nicht enthalten) sind nicht zugelassen.

Eine Methoden- oder Eigenschaftsdeklaration in einem automatisierten Abaschnitt kann die optionale Anweisung dispid enthalten die von einer ganzzahligen konstante, die die OLE-Automatisierungs-Dispatch-ID der Methode oder Eigenschaft angibt, befolgt werden. Wenn eine dispid-Anweisung nicht zugegen ist, wählt der Compiler automatisch eine Zahl, die um eins größer ist als die größte Dispatch-ID ist, die eine Methode oder Eigenschaft in dieser Klasse bzw. der Stammklasse verwendet. Die Angabe einer bereits verwendeten Dispatch-ID in einer dispid-Anweisung verursacht einen Fehler.


Siehe auch

Component visibility

private

protected

public

published


Begin...End Construct (Reserviertes Wort)
Begin ... End (Zusammengesetzte Anweisung)

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Die reservierten Wörter begin und end bilden aus mehreren Anweisungen eine zusammengesetzte Anweisung.

Die zusammengesetzte Anweisung wird als einzelne Anweisung behandelt.


Beispiel

(* zusammengesetzte Anweisung mit einer "if"-Anweisung *)

if First < Last then

begin

  Temp := First;

  First := Last;

  Last := Temp;

end;


Siehe auch

Anweisungen


Case (Reserviertes Wort)
Case

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Über Case-Anweisungen wird Quellcode in Abhängigkeit von den Eintriittsergebnissen oder -werten verzweigt.

Die Anweisung case besteht aus einem Ausdruck (dem Selektor) und einer Liste von Anweisungen, denen jeweils eine oder mehrere Konstanten (bezeichnet als case-Konstanten) oder das reservierte Wort else voranstehen. Der Selektor muß vom Typ Ordinal sein. Stringtypen sind daher als Selektoren ungeeignet.

Alle case-Konstanten müssen einheitlich sein und einen Ordinal-Typ besitzen, der zum Typ des Selektors kompatibel ist.

Wird über das Programm eine case Anweisung eingegeben, dann wird jeder Ausdruck ausgeführt, bis ein passender Wert gefunden wird. Danach führt das Programm die Aktionen aus, die mit diesem Ausdruck verbunden sind. War die Suche nicht erfolgreich, dann wird das Programm standardmäßig bei der else-Anweisung fortgeführt. Gibt es keinen else-Teil, dann wird die Ausführung mit der Anweisung fortgeführt, die direkt nach der case Anweisung folgt.

Die Bereiche innerhalb der case-Anweisungen dürfen sich nicht überlappen. So ist zum Beispiel folgende case-Anweisung nicht erlaubt:

case MySelector of

  5: Writeln('Special case');

  1..10: Writeln('General case');

end;

Wenn Sie die case-Konstanten in aufsteigender Reihenfolge angeben, dann kann der Compiler die Fälle zu Sprüngen optimieren, anstatt jedesmal Berechnungen durchführen zu müssen. Beispielsweise wandelt der Compiler folgende case Anweisung in Sprünge um:

case MySelector of

  1: Writeln('One');

  2: Writeln('Two');

  else Writeln('More');

end;

Für diese Version jedoch sind viele Berechnungen erforderlich:

case MySelector of

  2: Writeln('Two');

  1: Writeln('One');

  else Writeln('More');

end;


Beispiel

case Ch of

  'A'..'Z', 'a'..'z':  WriteLn('Letter');

  '0'..'9':            WriteLn('Digit');

  '+', '-', '*', '/':  WriteLn('Operator');

else

  WriteLn('Special character');

end;


Siehe auch

Else

Ausdruck

Anweisung


cdecl (Standard-Anweisung)
Cdecl

Siehe auch 	Standard-Anweisungen

Syntax

procedure A; cdecl;

Beschreibung

Die Anweisung cdecl gibt an, daß eine Prozedur oder Funktion die C/C++ Aufrufkonvention zum Passieren von Parameter verwendet.

Die C/C++ Aufrufkonvention passiert Parameters von links nach rechts, wobei die Parameter durch den Aufrufenden aus dem Stapel entfernt werden.

Die C/C++ Aufrufkonvention ist meistens zum Aufrufen von Routinen nützlich, die aus  dynamic-link libraries (DLLs)  exportiert worden sind und in C, C++ und anderen Sprachen verfaßt sind.


Siehe auch

Aufrufkonventionen

Pascal

Register

stdcall


Class (Reserviertes Wort)
Class

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort class wird beim Deklarieren eines Objekttyps oder einer Klassenmethode verwendet. Weiterhin kann mit diesem reservierten Wort ein Klassenreferenztyp definiert werden.

Ein Objekttyp ist eine Datenstruktur, die eine feste Anzahl von Komponenten enthält. Diese Komponenten stellen entweder ein Feld (das Daten eines bestimmten Typs enthält); eine Methode, die eine Operation für das Objekt durchführt; oder eine Eigenschaft dar.

Die Deklaration eines Feldes enthält einen Bezeichner, der das Feld benennt und dessen Datentyp angibt.

Die Deklaration einer Methode legt ein Prozedur-, Funktions-, Konstruktor- oder Destruktor-Heading fest.

Die Definition einer Eigenschaft benennt die Eigenschaft und deren Zugriffsmethoden. Außerdem können Informationen darüber enthalten sein, wie sich die Eigenschaft während des Streaming verhalten soll.

Ein Objekttyp kann Komponenten von einem anderen Objekttyp erben. Das erbende Objekt ist ein Nachkomme und das vererbende Objekt ein Vorfahre.

Der Bereich eines Objekttyps umfaßt sich selbst und alle seine Nachkommen.

Ein Klassenreferenztyp wird über die Folge der reservierten Wörter class of gefolgt von dem Namen einer Klasse definiert. Eine Variable des Typs Klassenreferenz kann zur Laufzeit gesetzt werden, um entweder auf die in der Deklaration benannte Klasse oder eine ihrer Unterklassen zu verweisen.


Siehe auch

Feld- und Objektkomponentenbezeichner

Objekttypbereich

Objekttypen


Const (Reserviertes Wort)
Const

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort const definiert einen Bezeichner, dessen Wert sich innerhalb des Blockes, der die Deklaration enthält, nicht ändern kann. Ein konstanter Bezeichner darf in seiner eigenen Deklaration nicht enthalten sein.

Object Pascal erlaubt konstante Ausdrücke.

Ausdrücke in Konstanten-Deklarationen müssen so geformt sein, daß sie vom Compiler während der Kompilierung ausgewertet werden können.


Siehe auch

Konstanten-Deklarationen

Ausdrücke

Typisierte Konstanten


Beispiele

(* Konstanten-Deklarationen *)

const

  MaxData  = 1024 * 64 - 16;

  NumChars = Ord('Z') - Ord('A') + 1;

  Message  = 'Hello world...';

(* Typed constants *)

const

  identifier: type = value;

  ...

  identifier: type = value;


Constructor (Reserviertes Wort)
Constructor

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Ein Konstruktor definiert die Aktionen, die mit dem Erstellen eines Objekts verbunden sind. Er muß mit dem reservierten Wort constructor deklariert werden. Alle Object Pascal-Objekte erben mindestens einen rudimentären Konstruktor von TObject.

Wird der Konstruktor aufgerufen, dann gibt er eine Referenz auf eine neu reservierte und initialisierte Instanz der Klassentyps zurück.


Siehe auch

Konstruktoren und Destruktoren

Destruktor

Bilden der Instanz von Objekten

Methode

Objekt

Virtuell


Default (Standard-Anweisung)
Default

Siehe auch 	Standard-Anweisungen

Syntax

Beschreibung

Über den Befehl default wird die Array-Standardeigenschaft eines Objekts angegeben.

Wenn eine Array-Eigenschaft als Standard deklariert wird, dann können Sie darauf zugreifen, indem Sie nur den Namen des Objekts verwenden.

Der Bezeichner default wird nur für solche Eigenschaften unterstützt, die vom Typ Ordinal und kleinen Mengentypen sind. Ist default in einer Eigenschaft enthalten, dann muß nach default eine Konstante folgen, die den gleichen Typ wie die Eigenschaft besitzt.

Wenn eine Eigenschaftendefinition keinen default- oder nodefault-Bezeichner enthält (oder enthalten darf), dann entsprechen die Ergebnisse denen, die aufgetreten wären, wenn in der Definition ein nodefault-Bezeichner enthalten gewesen wäre.


Siehe auch

Nodefault


Destructor (Reserviertes Wort)
Destructor

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Ein Destruktor definiert die Aktionen, die mit dem Entfernen eines Objekt verbunden sind. Er muß mit dem reservierten Wort destructor deklariert werden

Wird der Destruktor aufgerufen, dann wird der zuvor für das Objekt reservierte Speicher vom Destruktor freigegeben.

Destruktoren können virtuell sein. Sie enthalten selten einen Parameter.


Siehe auch

Konstruktor

Konstruktoren und Destruktoren

Objekt

Virtuell


Dispid (Standard-Anweisung)
Dispid

Siehe auch	Standard-Anweisungen

Beschreibung

Die Standardanweisung dispid wird verwendet, um eine OLE-Automatisierungs-Dispach-ID für eine Methode oder Eigenschaft, die in eine automatisierten Abschnitt dieser Klasse deklariert ist, anzugeben.


Siehe auch

automatisiert


Do (Reserviertes Wort)
Do

Siehe auch	Beispiel	Reservierte Wörter

Das reservierte Wort do wird in Verbindung mit den Anweisungen while, for, on und with verwendet. Über do wird angegeben, welche Anweisungen ausgeführt werden sollen, solange die Bedingung gültig ist.


Beispiel

while Ch = ' ' do Ch := GetChar;

for Ch := 1 to 100 do Ch := GetChar;

with Date[I] do month := 1;

on <exception> do...


Siehe auch

Except

For

While

With


Dynamic (directive)
Dynamic

Siehe auch 	Standard-Anweisungen

Beschreibung

Der Befehl dynamic definiert eine Methode als dynamisch. Dynamische Methoden entsprechen den virtuellen Methoden von der Semantik her. Virtuelle und dynamische Methoden unterscheiden sich lediglich in der Implementierung der Bearbeitung des Methodenaufrufs zur Laufzeit. In allen anderen Dingen können die beiden Methodentypen als gleich angesehen werden.

In der Implementierung virtueller Methoden mißt der Compiler der Geschwindigkeit der Aufrufbearbeitung mehr Gewicht bei als der Codegröße. Bei der Implementierung dynamischer Methoden dagegen wird der Codegröße mehr Gewicht beigemessen als der Geschwindigkeit bei der Aufrufbearbeitung.

Im allgemeinen sind virtuelle Methoden beim Implementieren eines polymorphen Verhaltens besonders effizient. Dynamische Methoden eignen sich nur in solchen Situationen, in denen eine Basisklasse eine große Anzahl virtueller Methoden und eine Anwendung eine große Anzahl nachfolgender Klassen deklariert, und diese Klassen nur wenige Überschreibungen der ererbten virtuellen Methoden enthalten.


Siehe auch

Methoden


Else (Reserviertes Wort)
Else

Siehe auch	Beispiel	Reservierte Wörter

Das reservierte Wort else wird als Standardbedingung in den Anweisungen if, case und try verwendet.


Beispiel

(* Verwenden einer if-Anweisung *)

if ParamCount <> 2 then

begin

  WriteLn('Bad command line');

  Halt(1);

end

else

begin

  ReadFile(ParamStr(1));

  WriteFile(ParamStr(2));

end;

(* Verwenden einer case-Anweisung *)

case Ch of

  'A'..'Z', 'a'..'z':  WriteLn('Letter');

  '0'..'9':            WriteLn('Digit');

  '+', '-', '*', '/':  WriteLn('Operator');

else

  WriteLn('Special character');

end;


Siehe auch

Case

If

Try


End (Reserviertes Wort)
End

Siehe auch	Beispiel	Reservierte Wörter

Das reservierte Wort end markiert das Ende eines Blockes. End kann mit den folgenden Anweisungen verwendet werden:

begin Bilden zusammengesetzter Anweisungen

case Bilden von case-Anweisungen

record Deklaration von Record-Typen

object Deklaration von Objekt-Typen

asm Aufruf des integrierten Assemblers

except Beenden einer Ausnahmeliste

finally Beenden eines abschließenden Blocks

Dem abschließenden end eines Moduls folgt ein Punkt. Dadurch wird bezeichnet, daß keine Anweisung mehr folgt.


Siehe auch

Asm

Begin

Case

Except

Finally

Object

Record


Beispiele

(* Bilden einer zusammengesetzten Anweisung mit begin *)

if First < Last then

begin

  Temp := First;

  First := Last;

  Last := Temp;

end;

(* mit einer case-Anweisung *)

case Ch of

  'A'..'Z', 'a'..'z':  WriteLn('Letter');

  '0'..'9':            WriteLn('Digit');

  '+', '-', '*', '/':  WriteLn('Operator');

else

  WriteLn('Special character');

end;

(* in Record-Typdefinitionen *)

type

  MyClass  = (Num, Dat, Str);

  Date   = record

    D, M, Y: Integer;

  end;

  Facts = record

    Name: string[10];

    case Kind: MyClass of

      Num: (N: real);

      Dat: (D: Date);

      Str: (S: string);

  end;

(* in Objekttypdefinitionen *)

type

Location = object

  X, Y: Integer;

  Procedure Init(PX, PY: Integer);

  Function GetX: Integer;

  Function GetY: Integer;

end;

(* mit asm *)

asm

  mov ax,1

  mov cx, 100

end;


Except (Reserviertes Wort)
Except

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort except markiert den Beginn der Liste von Fehlerbehandlungsroutinen in einem Fehlerbehandlungsblock.

Der Teil except stellt eine Liste bestimmter UAE-Fehler und Reaktionen auf diese dar. Jede von ihnen ist eine on..do-Anweisung. Kann keine der on..do-Anweisungen auf den aktuellen UAE-Fehler angewendet werden, dann wird die im Teil else angegebene Standardbehandlungsroutine ausgeführt.

Wenn in einem Fehlerbehandlungsblock ein Ausnahmezustand auftritt, dann wird die Ausführung sofort beim Teil except fortgeführt. Die Anwendung untersucht jede on..do-Anweisung, bis die gefunden wird, die auf den bestimmten ausgelösten UAE-Fehler angewendet werden kann. Existiert keine solche spezielle Behandlungsroutine im Block, dann führt die Anwendung die (über das reservierte Wort else angegebene) Standardbehandlungsroutine aus, wenn eine vorhanden ist.

Wird der UAE-Fehler durch eine Behandlungsroutine (ob spezielle oder Standardroutine) bearbeitet, dann kann der Fehler als abgefangen betrachtet werden. Das Fehlerobjekt wird gelöscht und die Ausführung wird nach dem Fehlerbehandlungsblock fortgeführt.

Erfolgt keine Fehlerbehandlung für den ausgelösten Fehler, dann verläßt die Ausführung den Block mit dem noch nicht abgefangenen Fehler.


Siehe auch

Else

Fehlerbehandlung

Finally

Try


Exports (Reserviertes Wort)
Exports

Siehe auch	Reservierte Wörter

Das reservierte Wort exports wird in DLLs verwendet. Mit diesem werden Prozeduren und Funktionen aufgeführt, die aus einer DLL exportiert werden.

Ein exports kann überall und beliebig oft im Deklarationsteil eines Programms oder einer Bibliothek stehen.

Die einzelnen Einträge in eine Klausel exports gegen die Bezeichner der Prozeduren oder Funktionen an, die exportiert werden sollen.

Die zu exportierende Prozedur oder Funktion muß jedoch deklariert werden, bevor die exports-Klausel aufgerufen wird. Diese Deklaration muß die Anweisung export enthalten

Sie können dem Bezeichner in der exports-Klausel einen eindeutigen Bezeichner und einen Punkt voranstellen; Dadurch entsteht ein vollständig qualifizierter Bezeichner.

Eine exports-Klausel kann außerdem enthalten:

Eine index-Klausel

Eine name-Klausel

Am schnellsten kann über den Index nach einem DLL-Eintrag gesucht werden.

Auch ein Programm kann eine exports-Klausel enthalten. Das geschieht jedoch selten, weil es unter Windows nicht gestattet ist, daß Anwendungsmodule Funktionen zwecks Verwendung durch andere Anwendungen exportieren.


Siehe auch

Dynamische Linkbibliotheken

Verwenden von DLLs

Schreiben von DLLs


External (Prozedur-Anweisung)
External

Siehe auch	Beispiel	Standard-Anweisungen

Über die Anweisung external ist Ihr Programm in der Lage, mit gesondert kompilierten Prozeduren und Funktionen zu arbeiten, die in der Programmiersprache Assembler geschrieben wurden oder sich in DLLs befinden.

Die external-Anweisung nimmt den Platz einer Deklaration sowie der Anweisungsteile ein, die ansonsten vorhanden wären.

Der externe Code für Assembler-Sprachroutinen wird mit der Pascal-Unit oder dem Programm über $L Dateiname-Compilerbefehle gelinkt.

Eine ausführliche Erläuterung zum Import von externen Routinen aus DLLs finden Sie unter Zugriff auf in DLLs gespeicherten Routinen.


Beispiele

{ Die folgenden Zeilen importieren Routinen aus einer externen Assembler-Sprachdatei. }

function GetMode: Word; external;

procedure SetMode(Mode: Word); external; {$L CURSOR.OBJ}

{ Die folgende Zeile importiert eine Funktion aus einer DLL. )

function GlobalAlloc(Flags: Word; Bytes: Longint): THandle; external 'KERNEL.DLL' index 15;


Siehe auch

DLLs

Funktionen

Prozeduren


File (Reserviertes Wort)
File

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Ein file-Typ (file=Datei) besteht aus einer linearen Folge von Daten. Verwenden Sie das reservierte Wort of, um file einen bestimmten Typ zuzuweisen. Dateien können jeden beliebigen Typ außer dem Typ file und Objekt annehmen.

Werden das Wort of und der Komponententyp nicht angegeben, gibt der Typ eine untypisierte Datei an.

Der vordefinierte file-Typ Text steht für eine Datei, die druckbare ASCII-Zeichen in Zeilen enthält.


Beispiel

(* Dateitypdeklarationen *)

type

  Person = record

    FirstName: string[15];

    LastName : string[25];

    Address  : string[35];

  end;

  PersonFile = file of Person;

  NumberFile = file of Integer;

  SwapFile = file;


Siehe auch

Of


Finalization (Reserviertes Wort)
Finalization

Siehe auch 	Reservierte Wörter

Syntax

Beschreibung

Der Finalization-Teil ist optional und kann nur erscheinen, wenn eine Unit auch einen initialization-Teil enthält. Der Finalization-Teil besteht aus dem reservierten Wort finalization, gefolgt von einer Liste von Ausdrücken, welche die Unit beenden. Finalization ist das gegenteil zu Initialisierung, und jede Ressource (Speicher, Dateien usw.), die von einer Unit während seiner Initialisierung erworben wird, werden typischerweise im Finalization-Teil wieder freigegeben.

Unit-Finalization-Teile laufen in umgekehrter Reihenfolge wie die Initialisierungen ab. Wenn Ihre Anwendung beispielsweise Units A, B und C in dieser Reihenfolge initialisieren, wird sie sie in der Reihenfolge C, B und A finalisieren.

Wenn eine Unit beginnt, ihren Initialisierungscode auszuführen, wird der dazugehörigen Finalization-Teil ausgeführt, wenn die Anwendung beendet ist. Der Finalization-Teil muß deshalb in der Lage sein, unvollständig initialisierte Daten zu bearbeiten, wenn durch einen Fehler der Initialisierungscode nicht vollständig ausgeführt werden konnte.


Siehe auch

Interface

Implementation

Initialization

Units


Finally (Reserviertes Wort)
Finally

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort finally markiert den Abschnitt eines geschützten Blocks, der in jedem Falle ausgeführt wird, auch wenn ein UAE-Fehler auftritt.

Beim Auftreten eines Fehlers müssen Sie vielleicht Aufräum-Code, z.B. zum Freigeben belegter Ressourcen, ausführen, bevor Sie den Fehler behandeln. Über den Block try..finally können Sie dies tun.

Alle Anweisungen innerhalb eines try..finally-Block werden normal ausgeführt, ungeachtet des aufgetretenen Fehlers und ungeachtet des Punktes, an dem die Ausführung sprunghaft zu den Anweisungen des finally-Teils übergeleitet wurde.

Beachten Sie, daß in einem try..finally-Block keine speziellen Fehler behandelt werden. Er gibt Ihnen nur die Möglichkeit, abzusichern, daß ein bestimmter Codeblock immer, ungeachtet irgendwelcher Ausnahmezustände, ausgeführt wird.


Siehe auch

Except

Fehlerbeandlung

Try

Schützen von Ressourcenbelegungen


For...To, For...Downto (Reserviertes Worts)
For ... To, For ... Downto

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Die Anweisung for bewirkt, daß die Anweisungen nach do für jeden Wert im Bereich zwischen dem Anfangs- und dem Endwert, inklusive, einmal ausgeführt werden.

For-Schleifen sind sinnvoll, wenn Sie zu Beginn genau wissen, wie viele Male die Schleife durchlaufen werden soll.

Die Laufvariable beginnt immer beim Anfangswert.

to	Mit to wird der Wert der Laufvariablen bei jedem Schleifendurchlauf um 1 erhöht. Der Anfangswert muß kleiner sein als der Endwert.

downto	Mit downto wird der Wert der Steuervariablen um jeweils 1 verringert. Der Anfangswert muß größer sein als der Endwert.

Für die Laufvariable gelten folgende Regeln:

Es muß sich um einen lokalen Variablenbezeichner handeln, der im Bereich des Blocks definiert ist.

Sie muß vom Typ Ordinal sein.

Die Anfangs- und Endwerte müssen eine Typzuweisung besitzen, die zum Ordinal-Typ der Laufvariable kompatibel ist.

Nachdem eine for Anweisung ausgeführt wurde, ist der Wert der Laufvariable undefiniert, wenn die Ausführung der for Anweisung nicht durch eine goto Anweisung unterbrochen wurde.


Beispiel

(* for ... to, for ... downto *)

for I := 1 to ParamCount do

  WriteLn(ParamStr(I);

for I := 1 to 10 do

  for J := 1 to 10 do

  begin

    X := 0;

    for K := 1 to 10 do

      X := X + Mat1[I, K] * Mat2[K, J];

    Mat[I, J] := X;

  end;


Siehe auch

Goto Anweisungen

Schleifen

Ordinal-Typen

Bereich


Forward (Reserviertes Wort)
Forward

Siehe auch	Beispiel	Standard-Anweisungen

Mit der Standard-Anweisung forward können Sie eine Prozedur oder Funktion deklarieren, wobei der Anweisungsblock erst zu einem späteren Zeitpunkt definiert werden muß.

Zwischen der forward-Deklaration und der Definition der Prozedur ist die Deklaration anderer Prozeduren und Funktionen möglich. Auf diese Weise ist eine Rekursion (der sich überkreuzende Bezug zwischen mehreren Prozeduren) möglich.

Nach der forward-Deklaration muß die Prozedur oder Funktion durch eine Deklaration des Anweisungsblocks der Routine definiert werden.

Diese Deklaration kann die Parameterliste des Prozedur- oder Funktionkopfs entbehren.

Einer Prozedur oder Funktion kann über eine external- oder eine assembler-Deklaration, jedoch nicht über eine andere forward-Deklaration definiert werden.


Beispiel

(* Forward-Prozedur *)

Procedure Flip(N: Integer); forward;

Procedure Flop(N: Integer);

begin

  WriteLn('Flop');

  if N > 0 then Flip(N - 1);

end;

Procedure Flip;

begin

  WriteLn('Flip');

  if N > 0 then Flop(N - 1);

end;


Siehe auch

Assembler

External


Function (Reserviertes Wort)
Function

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort Function definiert einen Programmteil, der einen Wert berechnet und als Funktionsergebnis zurückgibt.

Der Kopf der Function legt den Bezeichner, die formalen Parameter (soweit vorhanden) und den Ergebnistyp der Funktion fest.

Funktionen können Werte jeden Typs außer Dateitypen zurückgeben.

Eine Funktion kann nach dem Funktionskopf einen Deklarationsteil enthalten.

Dem Function-Kopf folgen:

der Deklarationsteil, in dem lokale Variablen, Typen, Labels, Konstanten, Prozeduren oder Funktionen deklariert werden.

Anweisungen, die ausgeführt werden, wenn die Funktion aufgerufen wird.

Der Anweisungsteil sollte zumindest eine Zuweisung enthalten, die dem Funktionsbezeichner einen Wert gibt. Das Funktionsergebnis ist der letzte zugewiesene Wert.

Anstatt Deklaration und Anweisungsteil kann eine Funktion folgendes enthalten:

Eine forward-Deklaration

Eine external-Deklaration

Die Variable Result in Funktionen

Jede Funktion besitzt implizit eine lokale Variable Result, die den gleichen Typ besitzt wie der Rückgabewert der Funktion. Wird Result ein Wert zugewiesen, dann wirkt sich das genauso aus, als wenn dieser Wert dem Namen der Funktion zugewiesen worden wäre. Eine Funktion wird durch Ausführung eines Funktionsaufrufs aktiviert. Dieser Funktionsaufruf übergibt den Funktionsbezeichner und die von der Funktion benötigten aktuellen Parameter, wenn vorhanden.

Außerdem können Sie jedoch auf der rechten Seite der Zuweisungsanweisung auf Result verweisen. Result baut eine Referenz zum aktuellen Rückgabewert auf und erzeugt keinen rekursiven Funktionsaufruf.


Siehe auch

Ausdruck

Funktionsaufrufe

Ordinal

Parameter

Zeiger

Real

String


Beispiel

(* Funktionsdeklaration *)

Function UpCaseStr(S: string): string;

var

  I: Integer;

begin

  for I := 1 to Length(S) do

  if (S[I] >= 'a') und (S[I] <= 'z') then

  Dec(S[I], 32);

  UpCaseStr := S;

end;


Goto (Reserviertes Wort)
Goto

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort goto übergibt die Programmausführung den Anweisungen unter dem Label, auf das in der aktuellen Anweisung verwiesen wurde.

Das Label muß sich im selben Block wie die goto-Anweisung befinden. Der Sprung darf nicht aus einer Prozedur oder Funktion hinausführen.


Siehe auch

Label


Beispiel

label 1, 2;

goto 1

   .

   .

   .

1: WriteLn ('Abnormal program termination');

2: WriteLn ('Normal program termination');


If...Then...Else (Reserviertes Worts)
If ... Then ... Else

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

If, then und else geben die Bedingungen an, unter denen eine Anweisung ausgeführt wird.

Ist der  Boolesche Ausdruck nach if gleich True, dann werden die Anweisungen nach then ausgeführt.

Ansonsten werden die Anweisungen nach else ausgeführt. Gibt es keinen else-Teil, dann wird die Ausführung bei der nächsten Anweisung fortgesetzt, die der if-Anweisung folgt.

Hinweis:	Vor einer else-Klausel darf kein Strichpunkt gesetzt werden.


Siehe auch

Boolesche Typen

Bedingte Anweisungen

Else


Beispiel

(* if-Anweisungen *)

if (I < Min) oder (I > Max) then I := 0;

if x < 1.5 then

  z := x + y

else

  z := 1.5;


Implementation (Reserviertes Wort)
Implementation

Siehe auch	Reservierte Wörter

Der Implementation-Teil einer Unit enthält den Programmteil aller öffentlichenProzeduren und Funktionen, die im interface-Teil der Unit deklariert wurden. Er deklariert auch Konstanten, Typen, Variablen, Prozeduren und Funktionen, die privat sind.

Syntax

Beschreibung

Der implementation-Teil einer Unit ist der private Teil. In diesem Teil enthaltene Deklarationen können nur in diesem Abschnitt der Unit verwendet werden. Alle Konstanten, Typen, Variablen, Prozeduren und Funktionen, die im interface-Teil deklariert wurden, sind im implementation-Teil sichtbar.

Implementierungen von Prozeduren und Funktionen, die im interface-Teil deklariert wurden, können in jeder Abfolge des implementation-Teils definiert werden.

In der Implementierung kann eine uses-Klausel unmittelbar nach dem reservierten Wort implementation folgen. Wenn Sie eine uses-Klausel in den Interfaceteil einer Unit einfügen, dann sind die in der uses-Klausel aufgeführten Units für die definierende Unit nicht sichtbar.

Sind Prozeduren als external deklariert, sollten vor dem letzten end der Unit ein oder mehrere $L dateiname-Anweisungen in der Quelldatei stehen

Der Prozedur-/Funktionskopf in der Implementierung sollte entweder:

Mit der Deklaration im Interface identisch sein oder

Aus einer Kopfzeile bestehen.


Siehe auch

$L Dateiname

Interface

Initialization

Finalization

Units


Initialization (Reserviertes Wort)
Initialization

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Der optionale initialization-Teil einer Unit umfaßt das reservierte Wort initialization, gefolgt von einer Liste von Ausdrücken, die die Unit initialisieren.

Initialisierungsteile von Units innerhalb eines Programms werden in der gleichen Reihenfolge ausgeführt, in der die Units in der uses-Klausel des Hauptprogramms aufgeführt sind.


Siehe auch

Finalization

Units


Kopfzeilen (Prozeduren und Funktionen)

Siehe auch

Kopfzeilen sind im implementation-Teil deklarierte Prozeduren und Funktionen, die keine Parameter enthalten. Die Parameter einer Kopfzeile werden zuvor im interface-Teil aufgelistet oder als forward oder als Teil eines Objekttyps deklariert.

Für Kopfzeilen geben Sie das reservierte Wort (Prozedur oder Funktion) gefolgt vom Namen (Bezeichner) der Routine an.

Lokale Routinen im Implementationssteil (die nicht im Interface-Abschnitt deklariert sind) müssen mit einem vollständigen Prozedur-/Funktionskopf angegeben werden.


Siehe auch

Implementation


Index (Standard-Anweisung)
Index

Siehe auch	Beispiel	Standard-Anweisungen

Eine index-Klausel gibt eine Ordinalzahl für das Exportieren von Prozeduren oder Funktionen aus einer dynamischen Linkbibliothek (DLL) an. Wird in der exports-Klausel keine index-Klausel verwendet, dann weist der Compiler eine Ordinalzahl zu.

Eine Index-Klausel ist in einer exports-Klausel enthalten und besteht aus dem Wort Index, gefolgt von einer Integer-Konstante zwischen 1 und 32767.


Beispiel

procedure ImportByOrdinal; external 'TESTLIB' index 5;


Siehe auch

Dynamische Linkbibliotheken

Forward

Verwenden von DLLs

Schreiben von DLLs


Inherited (Reserviertes Wort)
Inherited

Siehe auch	Reservierte Wörter

Das reservierte Wort inherited kann verwendet werden, um den Vorfahren des Objekttyps der umschließenden Methode zu benennen.

Inherited kann nicht bei Methoden eines Objekttyps ohne Vorfahren verwendet werden, weil es kein deklarierendes Objekt gibt, von dem geerbt werden kann.


Siehe auch

Objekttypen


Inline (Reserviertes Wort)
Inline

Reservierte Wörter

Beschreibung

Das reservierte Wort inline wird in dieser Version von Object Pascal nivht verwendet. Es bleibt dennoch für einen künftigen Gebrauch reserviert.


Interface (Reserviertes Wort)
Interface

Siehe auch	Reservierte Wörter

Der Interface-Teil einer Unit bestimmt, was für jedes Programm (oder jede andere Unit), das diese Unit verwendet, sichtbar und zugänglich ist.

Syntax

Beschreibung

Der Interface-Teil beginnt mit dem reservierten Wort interface, welches unter der Unit-Kofpzeile erscheint, und endet vor dem reservierten Wort implementation.

Der Interface-Teil deklariert Konstanten, Typen, Variablen, Prozeduren und Funktionen für public. Dadurch können sie von anderen Programmen oder Units benutzt werden.

Der Interface-teil listet nur die Kopfzeile einer deklarierten Prozedur oder Funktion. Der Block der Prozedur oder Funktion folgt im implementation-Teil. Die Deklarationen der Prozeduren und Funktionen im Interface-Teil sind wie forward declarations, obwohl die Anweisung forward nicht verwendet wird.

Eine uses-Klausel kann im Interface-Teil erscheinen. (Wenn vorhanden, muß uses sofort dem reservierten Wort interface folgen).


Siehe auch

Implementation

Units


Label (Reserviertes Wort)
Label

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort label deklariert Labels, die Anweisungen im Anweisungsteil markieren. Die Steuerung wird über eine goto-Anweisung an das Label übergeben.

Jedes Label darf nur eine Anweisung markieren.

Außer einem Bezeichner kann eine Zahl zwischen 0 und 9999 als Label verwendet werden.


Siehe auch

Goto


Library (Reserviertes Wort)
Library

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Eine dynamische Linkbibliothek (DLL) beginnt mit einer library-Kopfzeile.

Diese Kopfzeile weist den Compiler an, eine ausführbare Datei mit der Kennzeichnung .DLL anstatt .EXE zu erzeugen.


Siehe auch

Exports-Klausel

Importieren von Units

Index-Klausel

Name-Klausel

Schreiben von DLLs


Maxint and MaxLongInt (constants)
MaxInt and MaxLongInt

MaxInt und MaxLongInt sind vordefinierte Konstanten. In dieser Version von Object Pascal heben sie den gleichen Wert.

MaxInt enthält den größten Integerwert (2,147,483,647).

MaxLongint enthält den größten Longintwert (2,147,483,647).


Name (Standard-Anweisung)
Name

Siehe auch	Standard-Anweisungen

Eine name-Klausel kann in einer exports-Klausel eingeschlossen sein. Sie besteht aus dem Wort name, gefolgt von einer Stringkonstante.

Bei Vorhandensein einer Namensklausel verwendet die Prozedur oder Funktion, die exportiert werden soll, den Namen in der Stringkonstante.

Wird keine Namensklausel verwendet, wird die Prozedur oder Funktion über ihren Bezeichner exportiert und dieser Bezeichner in Großbuchstaben verwandelt.


Siehe auch

Verwenden von DLLs

Exports

Index


Nil (Reserviertes Wort)
Nil

Reservierte Wörter

Beschreibung

Das reservierte Wort nil benennt eine Zeiger-Typkonstante, die auf nichts zeigt.

nil ist zu allen Zeigertypen kompatibel.


Nodefault (Standard-Anweisung)
Nodefault

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung nodefault steuert den Wert, der als Standardwert einer Eigenschaft betrachtet wird.

In einer Eigenschaftendeklaration ist nodefault ein optionaler Bezeichner. Ist er nicht enthalten, dann entsprechen die Ergebnisse denen, die zustande kommen würden, wenn der Bezeichner nodefault enthalten wäre.


Siehe auch

Default


Object (Reserviertes Wort)
Object

Siehe auch

Syntax

Beschreibung

Über das reservierte Wort object werden Objekttypen deklariert, die dem Objektmodell älterer Versionen von Borland und Turbo Pascal entsprechen. Neue Programme sollten das reservierte Wort class und das neue Objektmodell verwenden. Über das reservierte Wort object deklarierte Objekttypen und das veraltete Objektmodell dürfen keine Klassenmethoden enthalten. Sie dürfen auch keine Eigenschaften als Komponenten angeben.

Ein Objekttyp ist eine Datenstruktur, die eine feste Anzahl von Komponenten enthält.

Jede Komponente stellt entweder ein Feld (das Daten eines bestimmten Typs enthält) oder eine Methode dar, die eine Operation für das Objekt durchführt.

Die Deklaration eines Feldes enthält einen Bezeichner, der das Feld benennt, und den Datentyp des Feldes.

Die Deklaration einer Methode enthält eine Kopfzeile mit einem Prozedur-, einem Funktionskonstruktor, oder einem -destruktor.

Ein Objekttyp kann Komponenten von einem anderen Objekttyp erben. Das erbende Objekt ist ein Nachkomme und das vererbende Objekt ein Vorfahre.


Siehe auch

Feld- und Objektkomponentdesignatoren

Objekttypbereich

Objekttypen


Of (Reserviertes Wort)
Of

Siehe auch	Beispiel	Reservierte Wörter

Das reservierte Wort of wird in Array-, Set-, Class-, File-Typdeklarationen sowie in case-Anweisungen verwendet.


Siehe auch

Array

Case

File

Set


Beispiele

(* Array-Deklaration *)

type

  IntList = array[1..100]   of Integer;

  CharData = array['A'..'Z']  of Byte;

  Matrix   = array[0..9, 0..9] of real;

(* Mengentypen *)

type

  Day = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);

  CharSet = set of Char;

  Digits = set of 0..9;

  Days = set of Day;

(* Dateitypdeklarationen *)

type

  Person = record

     FirstName: string[15];

     LastName : string[25];

     Address  : string[35];

  end;

  PersonFile = file of Person;

  NumberFile = file of Integer;

  SwapFile = file;

(* case-Anweisung *)

case Ch of

  'A'..'Z', 'a'..'z':  WriteLn('Letter');

  '0'..'9':            WriteLn('Digit');

  '+', '-', '*', '/':  WriteLn('Operator');

else

  WriteLn('Special character');

end;


On (Standard-Anweisung)
On

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort on definiert die Reaktionen auf Ausnahmezustände. On ist immer mit dem reservierten Wort do gekoppelt. Beide zusammen bilden eine vollständige Fehlerbehandlungsroutine.

Der except-Teil eines try..except-Blocks umfaßt eine Liste mit einer oder mehreren on..do-Anweisungen zum Abfangen bestimmter UAE-Fehler.


Siehe auch

Fehlerbehandlungsanweisungen

Reaktionen auf UAE-Fehler

Do

Except

Try


Override (Standard-Anweisung)
Override

Beispiel	Standard-Anweisungen

Über die Anweisung override wird eine virtuelle oder dynamische Methode erneut definiert.

Wenn die Anweisung override zu die Deklaration einer Methode hinzugefügt wird, überschreibt die Methode die geerbten Implementationen der Methode. Das Überschreiben einer virtuellen Methode muß genau zu der Reihenfolge und den Typen von Parametern und dem Funktionsergebnis (falls vorhanden) der Methode passen.

Da es für virtuelle Methoden nun zwei Möglichkeiten der Bearbeitung gibt, VMT-basiert und dynamisch, wird für Methoden, die virtuelle und dynamische Methoden überschreiben, die Anweisung override directive verwendet, anstatt virtual oder dynamic zu wiederholen.


Beispiel

Im folgenden Beispiel wird override verwendet, um die ererbte Prozedur P zu ersetzen.

type
  TAnObject = class
    Procedure P; virtual;
  end;

  TAnotherObject = class(TAnObject)
    Procedure P; override;
  end;


Packed (Reserviertes Wort)
Packed

Siehe auch	Reservierte Wörter

Description

Das reservierte Wort packed gibt dem Compiler in einer strukturierten Typdeklaration an, daß die Datenspeicherung, selbst auf Kosten eines langsameren Zugriffs auf eine Komponente einer Variable dieses Typs, komprimiert werden soll.

Es hat jedoch in Object Pascal keine Auswirkung, weil das Packen der Daten automatisch erfolgt.


Siehe auch

Strukturierte Typen


Pascal (Standard-Anweisung)
Pascal

Siehe auch	Standard-Anweisungen

Beschreibung

Die Anweisung pascal gibt an, daß eine Prozedur oder Funktion die Pascal-Aufrufkonvention zum Passieren von Parametern verwendet.

Die Pascal-Aufrufkonvention passiert Parameter von links nach rechts, wobei Parameter von der funktion aus dem Stapel entfernt  werden.

Die Pascal-Aufrufkonvention ist meistens für den Aufruf von Routinen nützlich, die aus dynamischen Linkbibliotheken (DLLs) , die in  C, C++ und anderen Sprachen verfaßt wurden, exportiert werden.


Siehe auch

Aufrufkonventionen

cdecl

register

stdcall


Private (Standard-Anweisung)
Private

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung private wird innerhalb eines Objekts verwendet, um einen Komponentendeklarationsteil zu kennzeichnen.

Innerhalb des Moduls funktionieren private-Komponentbezeichner wie public-Komponentbezeichner.

Außerhalb des Moduls sind private-Komponentbezeichner unbekannt. Man kann nicht auf sie zugreifen.

Stellen Sie verbundene Objekttypen in das gleiche Modul (oder die gleiche Unit), so können diese untereinander auf die private-Komponenten des anderen zugreifen, ohne daß die private-Komponenten den anderen Modulen sichtbar sind.

Der Bereich von Komponentbezeichnern, die als private deklariert wurden, sind auf das Modul beschränkt, in dem Objekttypdeklaration enthalten sind.


Siehe auch

Objekte

Protected

Public

Bereichsregeln

Objekttypbereich

Units


Procedure (Reserviertes Wort)
Procedure

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Über Prozeduren können Sie zusätzliche Blöcke im Hauptprogrammblock verschachteln. Jede Procedure-Deklaration besitzt eine Kopfzeile, der ein Anweisungsblock folgt.

Im Prozedurkopf werden der Name der Prozedur und die formalen Parameter (falls vorhanden) angegeben.

Eine Prozedur wird von einer Procedur-Anweisung, aktiviert, die den Namen der Prozedur sowie die aktuellen Parameter, wenn vorhanden, angibt.

Dem Prozedurkopf folgt:

Eine Deklaration, die lokale Objekte deklariert.

Anweisungen zwischen begin und end, die beim Aufruf der Prozedur auszuführende Aktionen enthalten.

Hinweis:	Wenn der Prozedurname in einer Procedure-Anweisung innerhalb des Prozedurblocks verwendet wird, dann ruft sich die Prozedur selbst auf, während sie ausgeführt wird. Daraus ergibt sich eine Endlosschleife.

Statt der Deklarations- und Anweisungsteile kann eine Prozedur-Deklaration folgende Anweisungen enthalten:

assembler

external

forward


Beispiel

{ Procedure-Deklaration }

Procedure NumString(N: Integer; var S: string);

var

  V: Integer;

begin

  V := Abs(N);

  S := '';

  repeat

    S := Chr(N mod 10 + Ord('0')) + S;

    N := N div 10;

  until N = 0;

  if N < 0 then

    S := '-' + S;

end;


Siehe auch

Funktionen

Parameter

Procedure-Anweisungen

Prozedurale Typkonstanten

Aufrufvorgaben


Program (Reserviertes Wort)
Program

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort program steht zu Beginn eines Programms und gibt den Programmnamen an.


Siehe auch

Uses-Klausel

Labels

Konstanten

Typen

Variablen

Prozeduren

Funktionen

Anweisungen


Property (Reserviertes Wort)
Property

Siehe auch

Syntax

Beschreibung

Über das reservierte Wort property können Sie eine Eigenschaft deklarieren. Eine Eigenschaftendefinition innerhalb einer Klasse deklarert ein benanntes Attribut für Objekte der Klasse sowie die Aktionen, die mit dem Lesen und Schreiben des Attributs verbunden sind.


Siehe auch

Read

Write

Stored

Objekttypen


Protected (Standard-Anweisung)
Protected

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung protected wird in Objekttypdeklarationen verwendet.

Nachkommen des deklarierenden Typs können auf Komponenten, die als protected deklariert wurden, zugreifen.

Wird eine Komponente als protected deklariert, dann werden dadurch die Vorteile von public- und private-Komponenten kombiniert.

Sie können wie bei private-Komponenten Einzelheiten der Implementierung vor den Augen des Benutzers verstecken. Im Gegensatz zu private-Komponenten stehen protected-Komponenten jedoch immer noch den Programmierern zur Verfügung, die neue Objekte von den Objekten ableiten möchten, ohne dazu gezwungen zu sein, die abgeleiteten Objekte in derselben Unit deklarieren zu müssen.

Protected-Methoden sind beim Verbergen von Eigenschaftenimplementierungen besonders nützlich.


Siehe auch

Komponenten Sichtbarkeit

Private

Public

Published

Automated

Objekttypbereich


Public (Standard-Anweisung)
Public

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung public wird innerhalb von Klassentypdeklarationen verwendet.

Komponentenbezeichner, welche in public-Komponentenabschnitten deklariert sind, unterliegen bezüglich ihres Gültigkeitsbereichs keinen besonderen Beschränkungen.


Siehe auch

Komponenten Sichtbarkeit

Private

Protected

Public

Automated

Objekttypbereich


Published (Standard-Anweisung)
Published

Siehe auch	Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung published wird innerhalb von Objekttypdeklarationen verwendet.

Wird ein Teil eines Objekts als published deklariert, so werden für diesen Teil Laufzeittypinformationen erzeugt. Diese Informationen werden in das published-Interface der Anwendung eingefügt.

Innerhalb Ihrer Anwendung funktioniert ein published-Teil genauso wie ein public-Teil. Der einzige Unterschied besteht darin, daß andere Anwendungen über das published-Interface Informationen über diese Teile bekommen können.

Der Objektinspektor verwendet das published-Interface der Objekte in der Komponentenpalette, um die anzuzeigenden Eigenschaften und Ereignisse zu ermitteln.


Siehe auch

Komponenten Sichtbarkeit

Private

Protected

Public

Automated

Objekttypbereich


Read (Standard-Anweisung)
Read

Siehe auch	Beispiel

Syntax

Beschreibung

Über die Anweisung read können Sie eine Routine angeben, die den Wert einer Eigenschaft ermittelt.


Siehe auch

Write


Beispiel

property Color: TColor read GetColor write SetColor;


Record (Reserviertes Wort)
Record

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Ein Record enthält verschiedene Komponenten oder Felder, die aus verschiedenen Typen bestehen können.

Jede Feldliste ist eine durch Kommata unterteilte Liste von Bezeichnern, denen ein Strichpunkt und die Angabe eines Typs folgt.

Sie müssen das Feld in der Record-Typdeklaration benennen und ihm einen Feldtyp zuweisen.

Der variante Teil des Record-Typsyntaxdiagramms verteilt Speicherplatz für mehrere Felderlisten, wodurch Sie mehrere Möglichkeiten haben, auf die Informationen zuzugreifen. Jede Felderliste ist eine Variante, die den gleichen Platz im Speicher überlagert. Die einzelnen Varianten werden durch Konstanten voneinander unterschieden. Sie können jederzeit auf alle Felder aller Varianten zugreifen.

Der optionale Bezeichner, der Markierungsfeldbezeichner, stellt einen Bezeichner eines zusätzlich festgehaltenen Feldes --des Markierungsfeldes--des Datensatzes dar. Das Programm verwendet den Wert des Markierungsfeldes, um anzuzeigen, welche Variante derzeit aktiv ist.

Zugreifen auf Datensätze

Sie können auf den gesamten Datensatz oder jedes Feld einzeln zugreifen. Benötigen Sie Informationen über ein einzelnes Feld, dann geben Sie den Datensatznamen, einen Punkt und danach den Feldbezeichner an. Zum Beispiel,

TDateRec.Year

Enthält ein Datensatz einen Unterdatensatz, dann können Sie über die Kennung darauf zugreifen.


Beispiel

{ Record-Typdefinitionen }

type

  TClass  = (Num, Dat, Str);

  TDate   = record

     D, M, Y: Integer;

  end;

  Facts = record

    Name: string[10];

    case Kind: TClass of

      Num: (N: Real);

      Dat: (D: TDate);

      Str: (S: string);

  end;


Siehe auch

Feld- und Objektkomponentdesignatoren

Record-Typkonstanten

Datensatzbereich

With-Anweisungen


Register (Standard-Anweisung)
Register

Siehe auch	Standard-Anweisungen

Beschreibung

Die Anweisung register gibt an, daß eine prozedur oder Funktion die Register-Aufrufkonvention zum Passieren der Parameter verwendet. Dies ist die Standardaufrufkonvention von Object Pascal.

Die Register-Aufrufkonvention passiert die Parameter von links nach rechts, wobei die Parameter von der Funktion aus dem Stapel entfernt werden.

Die Register-Konvention verwendet bis zu drei CPU-Register zum Passieren der Parameter, wo die anderen Konventionen immer alle Parameter des Stapels passieren. Die Register-Konvention ist bei weitem die effizienteste Aufrufkonvention, da es häufig die erstellung eines Stapelrahmens vermeidet.


Siehe auch

Aufrufkonventionen

cdecl

pascal

stdcall


Repeat...Until (Reserviertes Worts)
Repeat...Until

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Die Anweisungen zwischen repeat und until werden wiederholt, bis der Boolesche Ausdruck True ergibt.

Die Sequenz wird mindestens einmal ausgeführt, weil der Boolesche Ausdruck jeweils erst nach der Ausführung der gesamte Folge ausgeführt wird.


Beispiel

{ Repeat-Anweisungen }

  repeat Ch := GetChar until Ch <> ' ';

  repeat

    Write('Enter value: ');

    ReadLn(I);

  until (I >= 0) und (I <= '9');


Siehe auch

Schleifen


Resident (Standard-Anweisung)
Resident

Standard-Anweisungen

Die Standard-Anweisung resident wird in einer exports -Klausel eingeschlossen.

Wenn resident verwendet wird, verbleibt die Exportinformation im Speicher, wenn die dynamische Linkbibliothek (DLL)geladen wird.

Die Option resident verkürzt die Zeit, die Windows benötigt, um einen DLL-Eintrag über dessen Namen zu suchen.

Wenn Client-Programme, die die DLL benutzen, Einträge mit Namen importieren, sollten sie mit der Standard-Anweisung resident exportiert werden.


Self (implicit parameter)
Self

Reservierte Wörter

Self ist ein impliziter Parameter, der immer übergeben wird, wenn eine Methode aufgerufen wird.

Self kann als Zeiger auf die Instanz, die die Methode aufrief, verwendet werden.

Er garantiert unter anderem, daß die korrekten virtuellen Methoden für diese bestimmte Objektinstanz aufgerufen werden und daß von der Objektmethode die richtigen Instanzdaten verwendet werden.


Set (Reserviertes Wort)
Set

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Das reservierte Wort set definiert eine Sammlung von Objekten desselben Ordinaltyps mit maximal 256 möglichen Werten.

Die Ordinalwerte der oberen und unteren Grenzen des Basistyps müssen im Bereich 0..255 liegen.

Ein Mengen-Konstruktor, der einen Mengentypwert darstellt, wird durch Ausdrücke in Klammern hergestellt. Jeder Ausdruck benennt einen Wert der Menge

Die Notation [] steht für eine leere Menge, die zu allen Mengen-Typen kompatibel ist.


Beispiel

{ Mengentypen }

  type

    Day = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);

    CharSet = set of Char;

    Digits = set of 0..9;

    Days = set of Day;

{ Mengenkonstruktoren }

  ['0'..'9', 'A'..'Z', 'a'..'z', '_']

  [1, 5, I + 1 .. J - 1]

  [Mon..Fri]


Siehe auch

Of

Mengentypen

Mengentypkonstanten


Stdcall (Standard-Anweisung)
Stdcall

Siehe auch	Standard-Anweisungen

Beschreibung

Die Anweisung stdcall gibt an, daß eine Prozedur oder Funktion die Windows-Standardaufrufkonvention zum Passieren der parameter verwendet.

Die Konvetion stdcall passiert die parameter von links nach rechts (wie die cdecl-Konvention), aber die Parameter werden durch die Funktion aus dem Stapel entfernt.

Die stdcall-Aufrufkonvention wird zum Audruf der Windows- API-Routinen verwendet.


Siehe auch

Aufrufkonventionen

cdecl

pascal

register


String (Reserviertes Wort)
String

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Über das reservierte Wort string wird eine Variable vom Typ String deklariert.


Siehe auch

Indizes

String-Typen


Stored (Standard-Anweisung)
Stored

Standard-Anweisungen

Syntax

Beschreibung

Die Anweisung stored steuert, ob eine Eigenschaft in einer Datei abgelegt wird oder nicht.

Wenn sich in einer Eigenschaftendefinition das Schlüsselwort stored befindet, dann muß ihm folgen:

Eine Boolesche Konstante (True oder False).

Der Bezeichner eines Feldes vom Typ Boolesch.

Der Bezeichner einer parameterlosen Funktionsmethode, die einen Booleschen Wert zurückgibt.

Wenn eine Eigenschaftendefinition keinen stored-Bezeichner enthält, dann werden die gleichen Ergebnisse erzielt, als wenn stored-True-Bezeichner enthalten gewesen wäre.


Threadvar (Reserviertes Wort)
Threadvar

Siehe auch	Reservierte Wörter

Das reservierte Wort threadvar wird zum deklarieren von thread-local-Variablen verwendet. Sein Syntax ist mit dem des reservierten Worts var identisch.


Siehe auch

Var


Try (Reserviertes Wort)
Try

Siehe auch	Beispiel	Reservierte Wörter

Über das reservierte Wort try wird der erste Teil eines geschützten Blocks markiert. Es gibt zwei Arten geschützter Blöcke::

try..except-Block

try..finally-Block

Syntax

Der try...except-Block

Ein Block, der UAE-Fehler behandelt, ist ein try..except-Block.

Innerhalb des try-Teils dieses Blockes werden die Anweisungen in der normalen Reihenfolge ausgeführt. Das geschieht unabhängig davon, welch ein Fehler aufgetreten ist und von welcher Stelle der except-Teil angesprungen wurde. Trat kein Fehler auf, dann endet der Block, ohne die Teile except oder else zu berühren.

Der except-Teil enthält eine Liste spezieller UAE-Fehler sowie Reaktionen auf diese. Dabei beginnen die Reaktionen jeweils mit einer on..do-Anweisung. Ist für den aktuellen UAE-Fehler keine on..do Anweisung vorhanden, dann wird die Standard-Fehlerbehandlungsroutine im else-Teil ausgeführt. Nachdem der Fehler durch eine Behandlungsroutine (ob spezielle oder Standardroutine) aufgefangen wurde, wird der Block beendet.

Die Ausführung wird danach außerhalb des Blockes fortgeführt. Im obigen Beispiel wird die Anweisung2 niemals ausgeführt, wenn Anweisung1 einen Fehler hervorruft.

Der try..finally-Block

Wenn Sie absichern möchten, daß die von Ihrer Anwendung belegten Ressourcen wieder freigegeben werden, dann können Sie die Ressourcenbelegungen durch einen try..finally-Block schützen.

Die im finally-Teil eines try..finally-Blockes enthaltenen Anweisungen werden in jedem Falle ausgeführt, selbst wenn ein Fehler aufgetreten ist.

Die Anweisungen im try..finally-Block werden normal ausgeführt, bis ein Fehler auftritt. Dann werden die Anweisungen im finally-Teil ausgeführt. Beachten Sie, daß im try..finally-Block selbst keine spezielle Fehlerbehandlung stattfindet.


Beispiel

Die folgenden Programmzeilen zeigen eine geschützte Ressource. Durch den Einbau einer Anweisung zum Schließen der Datei im finally-Teil des Blockes wird abgesichert, daß diese Datei in jedem Fall geschlossen wird, selbst bei Auftreten eines Fehlers.

var

  F: File;

begin

  Assign(F, 'SOMEFILE.EXT');

  Reset(F);

  try

    { Anweisungen, die auf Datei F zugreifen }

  finally

    Close(F);

  end;

end;


Siehe auch

Fehlerbehandlung

Schützen von Ressourcenbelegungen


Type (Reserviertes Wort)
Type

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Eine type-Deklaration spezifiziert einen Bezeichner , der seinerseits für einen bestimmten Typ steht.

Der Typ einer Variable definiert die Menge der Werte, die sie annehmen kann, sowie die Operationen, die mit ihr durchgeführt werden dürfen.


Siehe auch

Typdeklarationen


Unit (Reserviertes Wort)
Unit

Siehe auch	Reservierte Wörter

Syntax

Beschreibung

Units bilden die Grundlage der modularen Programmierung. Mit Units bilden Sie Bibliotheken und unterteilen große Programme in logisch bezogene Module.

Eine Unit setzt sich aus folgenden Komponenten zusamment,:

Unit-Kopf

interface-Teil

implementation-Teil

Initialisierungsteil

finalization-Teil

Unit-Kopf

Der unit-Kopf benennt die Unit. Dieser Name wird bei Bezug auf die Unit in einer uses-Klausel benützt.

Der Name muß eindeutig sein: Zur selben Zeit dürfen keine zwei Units mit dem gleichen Namen verwendet werden.


Siehe auch

Circular-Unitreferenzen

Indirekte Unitreferenzen


Uses (Reserviertes Wort)
Uses

Beispiel	Reservierte Wörter

Die Klausel uses identifiziert allel units, die vom Programm verwendet werden.

Syntax

Beschreibung

Jeder Bezeichner einer uses-Klausel benennt eine Unit , die Funktionen oder Prozeduren enthält, die vom aktuellen Programm oder von der aktuellen Unit verwendet werden.

Die System-Unit wird jedesmal automatisch verwendet. System implementiert all Low-Level-Laufzeit-Routinen, um solche Funktionen wie Dateiein- und ausgang (E/A), String-Handling, Gleitkomma, dynamische Speicherzuweisung memory allocation, and others.

Unabhängig von System implementiert Object Pascal viele Standard-Units, die ni cht automatisch verwendet werden; Sie müssen sie in Ihre uses-Klausel aufnehmen.

Die reihenfolge der Units in der uses-Klausel bestimmt die Reihenfolge ihrer Initialization.

Um eine Unit-Datei zu finden, die eine kompilierte Unit enthält, fügt der Compiler die Dateinamenerweiterung .DCU zum Unit-Namen hinzu, der sich in der uses-Klausel befindet.

Der Compiler durchsucht das aktuelle Verzeichnis, danach die unter Directories/Conditionals im Dialogfenster Optionen|Projekt angegebenen Verzeichnisse.


Beispiel

program MyProgram;

uses SysUtils;


Var (Reserviertes Wort)
Var

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Eine Variablendeklaration (var) verbindet einen Bezeichner und einen Typ mit einer Speicheradresse, an der Werte dieses Typs gespeichert werden können

Mit der absolute-Klausel wird eine absolute Speicheradresse benannt.

Das reservierte Wort var wird auch zur Deklaration von Variablenparametern verwendet.


Beispiel

{ Variablendeklarationen }

  var

    X, Y, Z: real;

    I, J, K: Integer;

    Done, Error: Boolean;

    Vector: array[1..10] of real;

    Name: string[15];

    InFile, OutFile: Text;

    Letters: set of 'A'..'Z';


Siehe auch

Globale und Lokale Variablen

Bereich

Variablendeklarationen


Virtual (Prozedur-Anweisung)
Virtual

Siehe auch	Standard-Anweisungen

Beschreibung

Über die Anweisung virtual wird eine virtuelle Methode.

Eine virtuelle Methode wird durch einen Prozeß, der als späte Verbindung bezeichnet wird, zur Laufzeit mit ihrem Code verbunden.

Wenn eine Methode als virtuell deklariert wird, ist es möglich, für Methoden mit dem gleichen Namen verschiedene Implementierungen innerhalb der Objekt-Hierarchie zu haben.

Um eine Methode als virtuell zu deklarieren, muß nach der Deklaration der Methode das reservierte Wort virtual und ein Strichpunkt folgen.


Siehe auch

Objekte

Self

Virtuelle Methoden


While (Reserviertes Wort)
While

Siehe auch	Beispiel	Reservierte Wörter

Syntax

Beschreibung

Eine while-Anweisung enthält einen Ausdruck, der die wiederholte Ausführung einer Anweisung steuert (die eine zusammengesetzte Anweisung sein darf).

Die Anweisungen nach do werden so lange wiederholt ausgeführt, wie der Boolesche Ausdruck True ist.

Der Ausdruck wird ausgewertet, bevor die Anweisung ausgeführt wird. Wenn der Ausdruck False ist, werden die Anweisungen nicht ausgeführt.


Siehe auch

Zusammengesetzte Anweisungen

Do (reserviertes Wort)

For (reserviertes Wort)

Schleifen

Repeat (reserviertes Wort)


Beispiel

{ while-Anweisungen }

  while Ch = ' ' do Ch := GetChar;


With (Reserviertes Wort)
With

Siehe auch	Beispiel	Reservierte Wörter

Syntax:

Beschreibung

Die with-Anweisung ist ein Kürzel für den Bezug auf Felder eines Record und die Felder und Methoden eines Objekts.

Innerhalb einer with-Anweisung kann auf die Felder einer oder mehrerer Record-Variablen Bezug genommen werden, wobei nur die Angabe der Feldbezeichner nötig ist.

Innerhalb einer with-Anweisung wird jede Variablenreferenz zuerst darauf überprüft, ob sie als Feld des Records interpretiert werden kann. Wenn ja, dann wird sie in jedem Fall als solches interpretiert, auch wenn auf eine Variable mit dem gleichen Namen zugegriffen werden könnte.

Wenn die Auswahl einer Record-Variable das Indizieren eines Arrays oder das Dereferenzieren eines Zeigers betrifft, dann werden diese Aktionen ausgeführt, bevor die Komponentenanweisung ausgeführt wird.


Siehe auch

Records


Beispiel

type

   TDate = record

      Day : Integer;

      Month: Integer;

      Year : Integer;

   end;

var OrderDate: TDate;

with OrderDate do

  if Month = 12 then

  begin

    Month := 1;

    Year := Year + 1

  end

  else

    Month := Month + 1;


Write (Standard-Anweisung)
Write

Siehe auch	Beispiel

Syntax

Beschreibung

Die Anweisung write ist ein Eigenschaftenzugriffsbezeichner, über den Sie eine Routine angeben können, mit dem Sie den Wert einer Eigenschaft setzen können.


Siehe auch

Read


Typdeklarationen

Siehe auch	Sprachdefinition

Wenn Sie eine Variable deklarieren, müssen Sie ihren Typ festlegen. Typen können entweder vordefiniert sein oder vom Benutzer festgelegt werden. Vom Benutzer definierte Typen werden im Typdeklarations-Teil eines Programms oder einer Unit vereinbart.

Der Typ legt den Wertebereich der Variable fest und bestimmt die Operationen, die mit ihr  ausgeführt werden können.

Der Gültigkeitsbereich einer Typdeklaration erstreckt sich über den Block, in dem der Typ deklariert wird.

Der Gültigkeitsbereich eines Typbezeichners erstreckt sich nicht auf die Definition selbst (d.h. die Definition kann den zukünftig definierten Typ selbst nicht enthalten). Die einzige Ausnahme von dieser Regel stellen Zeigertypen dar.

Es gibt sechs Klassen von Typen:

1.	Einfache Typen definieren geordnete Wertemengen.

2.	Stringtypen definieren Zeichenfolgen mit dynamischer Länge, denen ein Speicherbereich konstanter Größe zugewiesen wird.

3.	Strukturierte Typen definieren eine Struktur, die mehr als einen Wert enthält.

4.	Zeigertypen definieren einen Menge von Werten, die auf Variablen eines festgelegten Typs zeigen.

5.	Prozedurale Typen ermöglichen es, Prozeduren und Funktionen als Objekte zu behandeln.

6.	Varianttypen gestatten Vriablen, Werte verschiedenen Typs zuzuweisen.


Siehe auch

Gültigkeitsbereich

Typenkompatibilität


Fundamental- und Generic-Typen

Typen

Object Pascals vordefinierten Typen werden in zwei Kategoriern unterteilt:

Fundamental-Typen

Generict-Tpen

Der Bereich und das Format von Fundamental-Typen ist von der zugrundeliegenden CPU und dem Betriebssystem unabhängig und ändert sich nicht bei verschiedenen Implementationen von Object Pascal.

Der Bereich und das Format von Generic-Typen hängt von der vorhandenen CPU und dem Betriebssystem ab.

Es gibt gegenwärtig drei Klassen von vordefinierten Typen, die zwischen Fundamental- und Generic-Typen unterscheiden:

Integer-Typen

Character-Typen

String-Typen

Für alle anderen Klassen sollten Sie die vordefinierten Typen als Fundamental-Typen ansehen.

Anwendungen sollten möglichst Generic-Formate verwenden, um beste Ergebnisse mit der zugrundeliegenden CPU und dem Betriebssystem zu erzielen. Die Fundamental-Typen sollten nur verwendet werden, wenn der aktuelle Bereich und/oder das Speicherformat  mit der Anwendung nicht korreliert.


Einfache Typen

Typen

EinfacheTypen definieren geordnete Wertemengen. Es gibt zwei Basisklassen von einfachen Typen:

Ordinale Typen

Realtypen

Ein Bezeichner vom Typ Real ist einer der Standardbezeichner Real, Single, Double, Extended oder Comp.

Vergleich von einfachen Typen

Beim Vergleich von einfachen Typen müssen die Operanden miteinander kompatibel sein. Wenn einer der Operanden vom Typ Real ist, kann der andere vom Typ Integer sein.


Ordinale Typen

Siehe auch	Typen

Ordinale Typen sind eine Untermenge der einfachen Typen und enthalten eine endliche Anzahl von Elementen.

Object Pascal besitzt zehn vordefinierte ordinale Typen und zwei vom Benutzer definierbare Typen. Die vordefinierten Typen sind:

Integer	Shortint	SmallInt	Longint

Byte	Word	Cardinal	Char

Boolean 	ByteBool	WordBool	LongBool

Die vom Benutzer definierbaren ordinalen Typen sind:

Aufzählungstypen

Teilbereichstypen

Alle Werte eines ordinalen Typs sind eine geordnete Menge. Jeder Wert kann über seine Index-Position innerhalb der Menge bestimmt werden. Mit Ausnahme der Werte vom Typ Integer hat das erste Element jedes ordinalen Typs die Indexposition 0, das nächste 1, und so weiter. Der Index eines Wertes vom Typ Integer ist der Wert selbst.

Sie können die folgenden Standardfunktionen für ordinale Typen verwenden:

Funktion	Wirkung

Ord	liefert die numerische Ordnung eines Elements innerhalb der Menge.

Pred	liefert den Vorgänger des Wertes. Beim ersten Wert im ordinalen Typ ergibt sich ein Laufzeitfehler, wenn die Wertbereichsüberprüfung {$R+} aktiviert ist. Diesen Fehler können Sie mit Exceptions behandeln.

Succ	liefert den Nachfolger des Wertes. Beim letzten Wert im ordinalen Typ ergibt sich ein Laufzeitfehler, wenn die Wertbereichsüberprüfung {$R+} aktiviert ist. Diesen Fehler können Sie mit Exceptions behandeln.

Low	bestimmt den niedrigsten Wert im Bereich des gegebenen ordinalen Typs.

High	bestimmt den höchsten Wert im Bereich des gegebenen ordinalen Typs.


Siehe auch

Behandlung von Exceptions

Kompatibilität der Datentypen

Typumwandlung von Variablen

Typumwandlung von Werten


Integer Typen

Siehe auch	Ordinale Typen

Die vordefiniertenObject Pascals Integertypen werden in Fundamental- und Generic-Typen unterteilt.

Anwendungen sollten möglichst Generic-Formate verwenden, um beste Ergebnisse mit der zugrundeliegenden CPU und dem Betriebssystem zu erzielen. Die Fundamental-Typen sollten nur verwendet werden, wenn der aktuelle Bereich und/oder das Speicherformat  mit der Anwendung nicht korreliert.

Fundamental-Typen

Die fundamentalen Integertypen sind:

Typ	Bereich	Format
Shortint	-128 .. 127	8-Bit mit Vorzeichen
SmallInt	-32768 .. 32767	16-Bit mit Vorzeichen
Longint	-2147483648 .. 2147483647	32-Bit mit Vorzeichen
Byte	0  ..  255	8-Bit ohne Vorzeichen
Word	0  ..  65535	16-Bit ohne Vorzeichen
Der Bereich und das Format von Fundamental-Typen ist von der zugrundeliegenden CPU und dem Betriebssystem unabhängig und ändert sich nicht bei verschiedenen Implementationen von Object Pascal.

Generic-Typen

Die generischen Integertypen sind Integer and Cardinal. Der Integertyp stellt eine generische Ganzzahl mit Vorzeichen dar, und der Cardinal-Typ stellt eine generische Ganzzahl ohne Vorzeichen dar. Die aktuellen Bereiche und Speicherformate des Generic-Typs variieren bei verschiedenen Implementationen von Object Pascal, entsprechen aber im Allgemeinen denen, die aus der effektivsten Integer-Operation der zugrundeliegenden CPU und des Betriebssystems resultieren.

Typ	Bereich	Format
Integer	-32768 .. 32767	16-Bit mit Vorzeichen
Integer	-2147483648 .. 2147483647	32-Bit mit Vorzeichen
Cardinal	0 .. 65535	16-Bit ohne Vorzeichen
Cardinal	0 .. 2147483647	32-Bit ohne Vorzeichen
Arithmetische Operationen

Arithmetische Operationen mit Operanden vom Typ Integer erfolgen mit 8-bit, 16-bit oder 32-bit Genauigkeit. Es gelten dabei die folgenden Regeln:

Eine Integerkonstante erhält den Integertypen mit dem kleinsten Bereich, der den Wert der Konstanten enthält.

Beide Operanden in einer binären Operation werden in den Integertyp mit dem kleinsten Bereich konvertiert, der alle möglichen Werte beider Typen enthält. Der Ergebnistyp des Ausdrucks ist dieser gemeinsame Typ.

Der Ausdruck auf der rechten Seite der Zuweisung wird unabhängig vom Platzbedarf oder Variablentyp auf der linken Seite ausgewertet.

Bytes werden zwischenzeitlich in Operanden vom Typ Word konvertiert, damit sie kompatibel mit Integer und Word sind, bevor der Ausdruck ausgewertet wird.

Hinweis: 	Sie können durch Typumwandlung Werte vom Typ Integer explizit in einen anderen Integertypen konvertieren.


Siehe auch

Kompatibilität der Datentypen

Typumwandlung von Werten

Typumwandlung von Variablen

Fundamental- und Generic-Typen


Boolescher Typ

Siehe auch	Ordinale Typen

Es gibt vier vordefinierte Boolesche Typen. Der Typ Boolean deklariert Variablen, die zu False oder True ausgewertet werden.

Typ	Speicher

Boolean	1 Byte

ByteBool	1 Byte

WordBool	Zwei Bytes (ein Word)

LongBool	Vier Bytes (zwei Words)

Meistens werden Boolesche Ausdrücke mit relationalen Operatoren und bedingten Anweisungen verwendet. Weil Boolesche Typen Aufzählungstypen sind, gelten die folgenden Beziehungen:

False < True

Ord(False) = 0

Ord(True) = 1

Succ(False) = True

Pred(True) = False

Boolean ist der bevorzugte Typ und verbraucht am wenigsten Speicherplatz; ByteBool, WordBool und LongBool sorgen für Kompatibilität mit anderen Sprachen und der Umgebung von Windows.

Boolesche Variablen können nur die Werte 0 (False) und 1 (True) annehmen; ByteBool, WordBool und LongBool hingegen können andere ordinale Werte annehmen, wobei 0 False entspricht und alle Werte ungleich Null True darstellen. Jedesmal wenn ein ByteBool, WordBool oder LongBool-Wert in einem Zusammenhang gebraucht wird, in dem ein einfacher Boolescher Wert erwartet wird, erzeugt der Compiler automatisch Code, der jeden Wert ungleich Null in den Wert True umwandelt.


Siehe auch

Boolesche Ausdrücke

Boolesche Operatoren

Bedingte Anweisungen

Relationale Operatoren

Kompatibilität der Datentypen


Character-Typen

Siehe auch	Ordinale Typen

Object Pascal definiert zwei fundamentale Character-Typen und einen generischen Character-Typ.

Die fundamentalen Character-Typen sind:

AnsiChar	Byte-Zeichen, werden entsprechend des erweiterten ANSI-Zeichensatzes geordnet.

WideChar	Wort-Zeichen, werden entsprechend des Unicode-Zeichensatzes geordnet. Die ersten 256 Unicode-Zeichen entsprechen den ANSI-Zeichen.

Der generische Character-Typ ist Char.

In der aktuellen Implementation von Object Pascal, entspricht Char dem Fundamental-Typ AnsiChar, aber Implementationen für andere CPUs und Betriebssysteme könnten Char als WideChar definieren. Wenn Code geschrieben wird, der beide Zeichen benötigt, verwenden Sie die Standardfunktion SizeOf anstelle einer hard-coded Konstanten für die Zeichengröße.

Der Funktionsaufruf Ord(Ch), bei dem Ch jeder Character-Typ-Wert sein kann, liefert die Ordinalität von Ch.

Eine Stringkonstante der Länge 1 kann durch einen konstanten Char-Wert dargestellt werden. Die Funktion Chr kann einen Integer-Wert in ein Zeichen mit dem entsprechenden Ordinalität umwandeln.


Siehe auch

Kompatibilität der Datentypen

Fundamental- und Generic-Typen


Aufzählungstypen

Siehe auch	Beispiel	Ordinale Typen

Aufzählungstypen weisen Elementen in einer Bezeichnerliste aufeinanderfolgende Werte zu. Das erste Element erhält den Wert 0, das zweite den Wert 1, und so weiter.

Der Compiler erkennt den Namen des Aufzählungstyps als Typ für die gesamte Bezeichnerliste.

Die Ordnung eines Bezeichners wird von seiner Position innerhalb der Bezeichnerliste bestimmt, in der er deklariert ist.

Verwenden Sie die Funktionen Succ und Pred, um sich durch die Elemente der Bezeichnerliste vorwärts oder rückwärts zu bewegen.

Wenn die Funktion Ord für den Wert eines Aufzählungstyps angewendet wird, liefert Ord einen Integer zurück, der unter Berücksichtigung der anderen Werte des Aufzählungstyps angibt, wo der Wert auftritt.


Siehe auch

Boolesche Typen

Kompatibilität der Datentypen

Typdeklarationen


Beispiel für einen Aufzählungstyp

type

  Farbe = (Kreuz, Karo, Herz, Pik);


Teilbereichstypen

Beispiel	Ordinale Typen

Ein Teilbereichstyp umfaßt einen Wertebereich aus einem ordinalen Typ, genannt Host-Typ. Die Definition eines Teilbereichstypen spezifiziert den kleinsten und den größten Wert im entsprechenden Teilbereich.

Beide Konstanten müssen vom selben ordinalen Typ sein.

Eine Variable vom Teilbereichstyp besitzt alle Eigenschaften des Host-Typs. Ihre Werte zur Laufzeit müssen innerhalb des angegebenen Bereichs liegen.

Eine syntaktische Mehrdeutigkeit entsteht bei konstanten Ausdrücken, weil der Compiler eine Typdefinition, die mit einer Klammer beginnt, als Aufzählungstyp definiert. Es gibt zwei Möglichkeiten, dieses Problem zu lösen:

reorganisieren Sie den ersten Teilbereichsausdruck, so daß er nicht mit einer Klammer beginnt.

setzen Sie eine Konstante gleich mit dem Wert des Ausdrucks und verwenden Sie diese Konstante in der Typdefinition.

Die Compileranweisung $R aktiviert die Bereichsüberprüfung für Teilbereichstypen.


Beispiele für Teilbereichstypen

Dies sind Beispiele für Teilbereichstype:

0..99

-128..127

Pik..Herz

Das folgende Beispiel ist eine mögliche Lösung für das Problem mit den konstanten Ausdrücken:

type

  Scale = 2 * (X - Y)..(X + Y) * 2;


Realtypen

Siehe auch	Typen

Ein Realtyp ist eine Untermenge der reellen Zahlen, die als Gleitkommazahl mit einer festen Stellenanzahl dargestellt werden können.

Es gibt fünf Arten von Realtypen. Sie unterscheiden sich in ihrem Wertebereich, der Genauigkeit der Werte und im Speicherplatzbedarf.

		Significante	Bedarf in
Typ	Bereich	Stellen	Byte
Real	2.9 * 10e-39 .. 1.7 * 10e38	11-12	6
Single	1.5 * 10e-45 .. 3.4 * 10e38	7-8	4
Double	5.0 * 10e-324 .. 1.7 * 10e308	15-16	8
Extended	3.4 * 10e-4932 .. 1.1 * 10e4932	19-20	10
Comp	-2e63+1 .. 2e63-1	19-20	8
Currency	-922337203685477.5808..922337203685477.5807	19-20	8
Der Typ Comp (computational) speichert nur integrierteWerte von -2e63+1 bis 2e63-1 (näherungsweise  -9.2 * 10e18 bis 9.2 * 10e18.

Der Typ Currency ist ein Datentyp mit festgelegtem Punkt für Finanzberechnungen. Er wird als 64-Bit Integer-Wert gespeichert, wobei die vier am wenigsten signifikanten Ziffern vier Dezimalstellen darstellen.


Zeigertypen

Siehe auch	Beispiel	Typen

Ein Zeigertyp ist ein Wert, der auf Variablen eines Basistyps zeigt. Eine Variable vom Typ Pointer enthält die Speicheradresse einer Variablen.

Wenn der Basistyp ein nicht deklarierter Bezeichner ist, müssen Sie ihn im selben Teil der Typdeklaration wie den Zeigertyp deklarieren.

Sie können einer Zeigervariable folgendermaßen einen Wert zuweisen:

Prozedur/Funktion	Wirkung

New	allokiert einen neuen Speicherbereich für eine dynamische Variable im Heap der Anwendung und speichert die Adresse dieses Bereichs in der Zeigervariable.

@-Operator	richtet die Zeigervariable auf den Speicherbereich, der eine beliebige existierende Variable, den Einsprungpunkt einer Prozedur oder Funktion oder eine Variable enthält, die bereits einen Bezeichner besitzen.

GetMem	erzeugt eine neue dynamische Variable mit der angegebenen Größe und speichert die Adresse des Blocks in der Zeigervariable.

Das reservierte Wort nil bezeichnet eine Zeigerkonstante, die auf nichts zeigt.

Vergleich von Zeigern

Die Operatoren = und <> können für kompatible Operanden vom Typ Pointer verwendet werden. Zwei Zeiger sind nur dann gleich, wenn sie auf dasselbe Objekt zeigen.

Kompatibilität

In Object Pascal dürfen undeklyarierte Bezeichner in der Deklaration von Zeigern nur im folgenden Zusammenhang verwendet werden:

type
PointerType = ^UndefinedType;

wobei UndefinedType später in demselben Typendeklarationsbloch definiert wird.


Siehe auch

Zeigertyp-Konstanten

Zeiger und dynamische Variablen

Kompatibilität der Datentypen

Typ Pointer

Typ PChar

Typumwandlung von Werten


Typ Pointer

Siehe auch

Der vordefinierte Typ Pointer ist ein untypisierter Zeiger.

Sie können keine Variablen vom Typ Pointer dereferenzieren, indem Sie das Zeigersymbol ^ nach einer solchen Variable setzen. Dies ergibt einen Fehler.

Sie können generische Zeiger durch Typumwandlung dereferenzieren.

Werte vom Typ Pointer sind mit allen anderen Zeigertypen kompatibel.


Siehe auch

Zeigertypen

Zeiger und dynamische Variablen

Kompatibilität der Datentypen

Typ PChar

Typumwandlung von Variablen


Character-Pointer-Typen

Siehe auch

Object Pascal definiert zwei grundlegende Character-Pointer-Typen nd einen allgemeinen Character-Pointer-Typen.

Character-Pointer Typen sind einfach Zeiger auf Charakter-Typen, aber Object Pascal unterstützt erweiterte Syntax-Regeln, die den Umgang mit Null-Terminated-Zeichenketten vereinfachen.

Die grundlegenden Typen sind:

PAnsiChar	Ein Zeiger auf eine Null-Terminated-Zeichenkette mit Zeichen des Typs AnsiChar

PWideChar	Ein Zeiger auf eine Null-Terminated-Zeichenkette mit Zeichen des Typs PWideChar

Der allgemeine Typ ist:

PChar	Ein Zeiger auf eine Null-Terminated-Zeichenkette mit Zeichen des Typs Char

Die Unit System deklariert die Typen wie folgt:

type

  PAnsiChar = ^AnsiChar;

  PWideChar = ^WideChar;

  PChar = PAnsiChar;

Die grundlegenden Zeigertypen sind Zeiger auf grundlegende Zeichen (oder auf Null-Terminated-Zeichenketten auf solche Zeiger), und der allgemeine Zeigertyp verweist auf allgemeine Zeichen.

Comparing Vergleichen von Character-Pointern

Object Pascalgestattet die Verwendung der Operatoren <, >, <=, or >= auf die Werte der Character-Pointer. Diese relationalen Tests nehmen an, daß die beiden verglichenden Zeiger auf dasselbe Character-Array zeigen und damit die Operatoren nur den Versatz der beiden Werte vergleichen.

Zeigen die Pointer auf verschiedene Arrays, ist das Ergebnis nicht definiert.


Siehe auch

Operatoren für Zeiger auf Zeichen

Nullterminierte Strings

Zeigertypen

Relationale Operatoren

Kompatibilität der Datentypen

Typ Pointer


Beispiel für einen Zeigertyp

{ Zeigertyp-Deklaration }

type

  BytePtr  = ^Byte;

  WordPtr  = ^Word;

  IdentPtr = ^IdentRec;

  IdentRec = record

    Ident: string[15];

    RefCount: Word;

    Next: IdentPtr;

  end;


StandardPointers;PAnsiString;PByteArray;PCurrency;PExtended;PShortString;PTextBuf;PVarRec;Pvariant;PWordArray
Standardzeiger

Siehe auch

Wenn Sie eine Struktur oder einen Datentyp in Pascal definieren, sollten Sie auch einen Zeiger auf diesen Datentyp definieren. Für viele fortgeschrittene Programmiertechniken, wie z.B. verknüpfte Listen von dynamisch zugewiesenen Datensätzen, könnte es erforderlich sein, Zeiger anstelle von Variablenlisten zu verwenden.

Wenn Sie eine Variable definieren, erzeugt der Compiler den notwendigen Code zum Initialisieren und Abschließen dieses Typs automatisch. Wenn Sie Code schreiben, der Zeiger auf dynamische Strukturen, wie AnsiString und Variant, zuweist und freigibt, werden spezielle Initialisierungenund Abschlüsse benötigt.

In der folgenden Tabelle finden Sie einige Zeiger:

Zeiger	Zeigt auf
PAnsiString	eine AnsiString-Variable.
PByteArray	eine Variable des Typs TByteArray. Wird oft verwendet, um dynamisch zugewiesene Speicherblöcke für den Array-Zugriff zu typisieren.
PCurrency	eine Variable des Typs Currency.
PExtended	eine Variable des Typs Extended.
PTextBuf	eine Variable des Typs TextBuf. TextBuf ist der interne Puffer, der im TTextRec-Textdateidatensatz verwendet wird..
PVarRec	eine Variable des Typs TVarRec.
PVariant	eine Variable des Typs Variant.
PWordArray	eine Variable des Typs TWordArray. Wird oft verwendet, um  dynamisch zugewiesene Speicherblöcke für die Verwendung als ein Array für Werte in Wortgröße (2 Byte ohne Vorzeichen) zu typisieren.


Siehe auch

Operatoren für Zeiger auf Zeichen


Prozedurale Typen

Siehe auch	Beispiel	Typen

Prozedurale Typen ermöglichen es, Prozeduren und Funktionen an Variablen zuzuweisen oder als Parameter zu übergeben.

Der Syntax der Deklaration für einen prozeduralen Typ ist derselbe wie bei einer Prozedur oder einer Funktion mit der Ausnahme, daß der Bezeichner hinter dem Schlüsselwort procedure oder function entfällt.Die Deklaration eines prozeduralen Typs kann allerdings eine Konvention für ihren Aufruf festlegen. Die Vorgabe-Aufruf-Konventionen sind register.

Es gibt zwei Arten prozeduraler Typen:

Globale Procedur Zeiger

Methoden Zeiger

Sie können keine Funktionen deklarieren, die prozedurale Typen als Wert zurückliefern. Sie können aber die Adresse einer Prozedur oder Funktion zurückliefern, indem Sie einen Rückgabewert vom Typ Pointer verwenden und diesen dann in einen prozeduralen Typen umwandeln.

Ein Rückgabewert muß zu einem der folgenden Typen gehören:

string

real

integer

char

Boolean

Pointer

vom Benutzer definierte enumeration

Prozedurale Kompatibilität der Datentypen

Damit prozedurale Typen untereinander kompatibel sind, gelten folgende Bedingungen:

Beide Typen müssen die gleichen Aufrufkonventionen haben.

Beide Typen müssen die gleiche Anzahl Parameter haben.

Parameter an gleichen Positionen müssen vom selben Typ sein.

Der Typ des Rückgabewerts von Funktionen muß identisch sein.

Der Wert nil ist mit jedem prozeduralen Typen kompatibel.

Hinweis:	Parameternamen haben beim Bestimmen der prozeduralen Kompatibilität der Datentypen keine Bedeutung.


Siehe auch

Prozedurale Konstanten

Prozedurale Werte

Typ Pointer

Typumwandlung von Variablen


Beispiele für prozedurale Typen

type

  Proc = procedure;

  SwapProc = procedure(var X, Y: Integer);

  StrProc = procedure(S: string);

  MathFunc = function(X: Double): Double;

  DeviceFunc = function(var F: Text): Integer;

  MaxFunc = function(A, B: Double; F: MathFunc): Double;

var

  P: SwapProc;

  F: MathFunc;

procedure Swap(var A, B: Integer);

var

  Temp: Integer;

begin

  Temp := A;

  A := B;

  B := Temp;

end;

function Tan(Angle: Double);

begin

  Tan := Sin(Angle) / Cos(Angle);

end;

{ Sie können den Variablen P und F die folgenden Werte zuweisen }

P := Swap;

F := Tan;

{ Die folgenden Aufrufe mit P und F sind jetzt erlaubt }

P(I, J);       { gleichbedeutend mit Swap(I, J) }

X := F(X);     { gleichbedeutend mit X := Tan(X) }


Globale Prozedur-Pointer

Siehe auch	Beispiel

Ein globaler Prozedur-Pointer ist ein prozeduraler Typ, der ohne of object deklariert wird.

Globale Prozedur-Pointer können sich auf eine globale Prozedur oder Funktion beziehen und werden als Pointer verarbeitet, die Adresse einer globalen Prozedur oder Funktion speichern.


Siehe auch

Methoden-Pointer

Procedurale Typen


Beispiel

type

  TProcedure = procedure;

  TStrProc = procedure(const S: string);

  TMathFunc = function(X: Double): Double;'


Prozedurale Werte

Siehe auch	Beispiel

Sie können einer Prozedurtyp-Variable einen prozeduralen Wert zuweisen.

Prozedurale Werte sind:

der Wert nil

eine Variablenreferenz eines prozeduralen Typs

ein Bezeichner einer Prozedur oder Funktion

Ein Methoden-Designator

Wenn Sie eine Prozedur oder eine Funktion als einen prozeduralen Wert deklarieren, wird dies als Konstantendeklaration betrachtet.

Die Verwendung einer prozeduralen Variable mit dem Wert nil in einem Prozedur- oder Funktionsaufruf verursacht einen Fehler. nil deutet eine nicht zugewiesene prozedurale Variable an. Prozeduranweisungen oder Funktionsaufrufe, die eine prozedurale Variable nil betreffen, sollten folgenden Test verwenden. Der Operator @ gibt an, daß P untersucht und nicht aufgerufen wird.

if @P <> nil then P(I, J);

Die folgenden Typen von Prozeduren und Funktionen können nicht als prozedurale Werte verwendet werden:

Standard

eingeschachtelt

Methoden

inline

Obwohl Sie Standardprozeduren und -Funktionen nicht direkt als prozedurale Werte verwenden können, gibt es einen Umweg, indem Sie eine neue Funktion oder Prozedur deklarieren, die die Standardprozedur oder -Funktion in ihrem Rumpf aufruft.


Siehe auch

Prozedurale Typen

Kompatibilität der Datentypen

Verwendung von prozeduralen Typen in Ausdrücken


Stringtypen

Siehe auch	Beispiel	Typen

Object Pascal unterstützt zwei Arten von Strings:

kurze Strings

lange Strings

Kurze und lange Strings können in Zuwisungen und Ausdrücken nebeneinander verwendet werden und der Compiler erzeugt automatisch den Code zur Durchführung der String-Typ-Umwandlung.

Der kurze String stellt einen statistisch zugewiesenen String dar, der eine maximale Länge zwischen einem und 255 Zeichen haben kann und eine dynamische Länge, die zwischen 0 und der Maximallänge liegt.

Der lange String-Typ stellt stellt einen dynamisch-zugewiesenen String dar, dessen maximallänge nur vom verfügbaren Speicherplatz beschränkt wird. Bei neuen Anwendungen wird die Verwendung des langen String-Typs empfohlen.

Hinweis	Eine neue Compiler-Anweisung, $H, prüft, ob das reservierte Wort string einen kuzen oder einen langen String darstellt. Im Standardfall, {$H+}, stellt string einen langen String dar und die Verwendung des Schlüsselworts string ist mit dem vordefinierten Bezeichner AnsiString identisch. Im Zustand {$H–}stellt string einen kurzen String mit einer Maximallänge von 255 Zeichen dar und die Verwendung des Schlüsselworts string ist mit dem vordefinierten Bezeichner ShortString identisch.

Zwei aufeinanderfolgende einzelne Zitate werden verwendet, um ein einzelnes Zitat in einem String anzuzeigen..


Beispiel

{ Definitionen für Stringtypen }

  const

    LineLen = 79;

  type

    Name = string[25];

    Line = string[LineLen];{ String Type Definitions }

  const

    LineLen = 79;

  type

    Name = string[25];

    Line = string[LineLen];


Siehe auch

String (Reserviertes Wort)

String-Operatoren

String-Konstanten

Kompatibilität der Datentypen


Kurze String-Typen

Siehe auch 	Stringtypen

Ein kurzer String-Typ ist auf eine Maximallänge zwischen 1 und 255 Zeichen festgelegt Variablen vom Typ kurzer String können einen dynamische Länge zwischen 0 und der deklarierten Maximallänge besitzen.

Der vordefinierte Typ ShortString bezeichnet einen kuzen String-Typmit einer Maximallänge von 255 Zeichen.

Die Anzahl an Bytes, die eine Variable vom Typ kuzer String im Speicher belegt, entspricht der Maximallänge des kurzen String-Typs plus eins.

Wenn ein String-Wert einer kurzen String-Variablen zugeordnet wird, wird er gekürzt, wenn er länger als die angegebene Maximallänge der kurzen String-Variablen.

Sie können eine kurze String-Variable mit einemAusdruck indizieren, dessen Wert im bereich zwischen  0..N sein muß, wobei N die angegebene Maximallänge des kuzen Strings darstellt. Der Zeichentyp, auf den durch die Indizierung  des kurzen Strings zugegriffen wird, ist Char. Der Index des ersten Zeichens in einem String ist 1. Das Element beim Index 0 enthält die dynamische Länge des Strings. Bei einem kurzen String ist Length(S) mit Ord(S[0]) gleichzusetzen. Die dynamische Länge des Strings wird geändert, wenn dem nullten Element ein Wert zugewiesen wird, aber der Compiler prüft nicht, ob der Wert kleiner als die angegebene Maximallänge des Strings ist. Es ist möglich, einen kurzen String hinter seiner aktuellen Maximallänge zu indizieren. Die Zeichenwerte sind in diesem Fall undefiniert und Zuweisungen zu Zeichenpositionen hinter der aktuellen Länge beeinflußen den tatsächlichen Wert der kurzen String-Variablen nicht.

Die Standardfunktionen Low und High können auf eine kuze String-Variable  angewendet werden. In diesem Fall liefert Low Null und High die angegebene Maximallänge des kurzen String.


Siehe auch

Stringtypen

Lange Stringtypen

String (reserviertes Wort)


Lange Stringtypen

Siehe auch	Stringtypen

Der lange String-Typ wird von dem reservierten Wort string und den vordefinierten Bezeichner AnsiString bezeichnet.

Hinweis	Wenn Sie den Zustand des Compilers von $H nach {$H-}ändern,bezeichnet das reservierte Wort string einen kurzen String mit einer Maximallänge von 255 Zeichen. Der vordefinierte Bezeichner AnsiString bezeichnet immer einen langen String-Typ.

Lange Strings werden dynamisch zugewiesen und haben keinw deklarierte Maximallänge. Die theoretische Maximallänge eines langen String-Werts beträgt zwei Gigabyte (2 GB). In der praxis bedeutet das, daß die Maximallänge nur von dem einer Anwendung verfügbaren Speicher limitiert wird.

Die Verwaltung des dynamisch zugewiesenen Speichers einer langen string-Variablen geschieht ganz automatisch  und erfordert keinen zusätzlichen Benutzer-Code. Die automatische Verwaltung von langen strings besitzt die folgenden Charakteristika:

Eine lange String-Variable belegt vier Byte Speicher, die einen Hinweis auf den dynamisch zugewiesenen String enthalten. Wenn eine lange String-Variable leer ist (eine Zeichenkette mit Nullänge enthält), lautet der String-Zeiger nil und keine dynamischer Speicher ist mit der String-Variablen verknüpft. Für einen String, der nicht leer ist, weist der String-Zeiger auf einen dynamixh zugewiesenen Speicherblock, der den String-Wert, einen 32-Bit-Längenindikator und einen 32-Bit-Referenzzähler enthält

Lange Strings werden „Referenz-gezählt“. Wenn einer langen String-Variablen ein neuer Wert zugewiesen wird,  wird die referenzzahl seines vorigen Werts (sofern es kein leerer Wert war) erniedrigt und die Referenzzahl seines neuen Werts (sofern kein leerer Wert)  erhöht. Wenn die Referenzzahl eines String-werts Null erreicht, wird der dynamisch zugewiesene Speicher, der den String-Wert enthält, nicht weiter zugewiesen. Das Referenzzählen reduziert das Kopieren von String-Daten und die Speicherbeegung enorm. Die einzigen Daten, die in einer langen String-Zuweisung kopiert werden, ist der 32-Bit-String-Zeiger und jede Anzahl von langen String-Variablen, die sich auf den gleichenWert beziehen, ohne zusätzlichen Speicher zu belegen. Dashalb werden lange String-Zuweisungen normalerweise schneller ausgeführt als kurze.

Wenn zum Ändern eines Werts eines einzelnen Zeichens in einer langen String-Variablen die Indizierung verwendet wird, wird erst eine Kopie des String-Werts erstellt, wenn die Referenz zur String-Wert-Referenzzahl größer als eins ist. Dies ist als Kopie-beim-Semantik-Schreiben bekannt, und garantiert, daß die Veränderungen nicht auch andere lange String-Variablen ändern, die sich auf den String-Wert beziehen.

Lange String-Variablen werden immer so initialisiert, daß sie bei der ersten Erstellung leer sind. Das gilt gleichwohl für globale, und lokale String-Variablen sowie String-Variablen, die Teil einer Struktur sind.

Wenn lange String-Variablen den Gültigkeitsbereich verlassen (wie beim Verlassen einer Funktion mit lokalen langen String-Variablen), wird der Referenzzähler ihrer Werte automatisch dekrementiert. Dies gilt für eine Funktion auch denn, wenn sie aufgrund einer Exception verlassen wird.

Sie können eine nicht leere lange String-Variable mit einer einfachen Index-Anweisung indizieren, deren Wert im Bereich 1..N liegen muß, wobei N die dynamische Länge des langen Strings darstellt. Der Zeichentyp, auf den durch die Indizierung eines langen String zugegriffen wird ist ein Char. Der Index des ersten Zeichens in einem langen String ist 1. Anders als bei kurzen Strings haben die langen Strings keine nulltes Element, das die dynamische String-Länge enthält. Um die Länge eines langen Strings zu ermitteln, müssen Sie die Standardfunktion Length verwenden. Um die Länge eines langen Strings zu setzen, müssen Sie die Standardprozedur SetLength verwenden.

Während es möglich ist, eine Zeichenposition zuzuweisen, die durch das Indizieren eines langen Strings ermittelt wird, ist es nicht möglich so ein Zeichen als var-Parameter zu übergeben.

Wenn Sie lange String-Felder in einem Record deklarieren, müssen all diese Felder im nicht-varianten Teil des Records verbleiben. Mit anderen Worten, lange String-Felder eines Typs, der lange Strings enthält, sind nicht im varianten Teil eines Records erlaubt.

Lange Strings und null-beendete Strings

Dynamischer Speicher, der für einen langen String-Wert belegt wird, wird automatisch durch ein Null-Zeichen beendet (das Zeichen Null ist nicht Bestandteil des Strings, sondern wird automatisch direkt nach dem letzten Zeichen im String gespeichert). Wegen der automatischen Begrenzung durch das Zeichen Null ist es möglich direkt eine Typumwandlung eines langen String-Wertes in einen PChar-Wert vorzunehmen. Die Syntax einer solchen Umwandlung lautet PChar(S), wobei S ein langer String-Ausdruck ist. Eine PChar-Typumwandlung gibt einen Zeiger auf das erste Zeichen der langen String-Variablen zurück und garantiert die Rückgabe eines Zeigers auf einen durch Null beendeten String, auch wenn die String-Anweisung leer ist.

Das folgende Beispiel zeigt wie PChar-Typumwandlungen verwendet werden können, um lange String-Werte an eine Funktion zu übergeben, die null-begrenzte String-Parameter erwartet. Caption und Message sind lange String-Varaiblen und MessageBox ist eine Win32-API-Funktion, die in der Interface-Unit von Windows definiert ist.

Caption := 'Hello world';

Message := 'This is a test of long strings';

MessageBox(0, PChar(Message), PChar(Caption), MB_OK);

Es ist ebenfalls möglich eine Typumwandlung eines langen Strings auf einen nicht typisierten Zeiger durchzuführen, indem Sie die Syntax Pointer(S) verwenden, wobei S einen langen String-Ausdruck darstellt. Eine Zeiger-Typumwandlung gibt die Adresse des ersten Zeichens des langen String-Wertes zurück. Anders als eine PChar-Umwandlung gibt eine Zeiger-Umwandlung nil zurück, wenn der String-Ausdruck leer ist.

Die Lebensdauer eines Zeigers, der von einer PChar oder Zeiger-Umwandlung zurückgegeben wird, hängt von dem Argument der Umwandlung ab. Wenn das Argument einen langen String-Ausdruck darstellt, bleibt der Zeiger nur innerhalb der Anweisung gültig, in der die Umwandlung durchgeführt wird. Dadurch wird so eine Typumwandlung elementar auf die Verwendung in Parameter-Ausdrücken begrenzt. Ist das Argument eine lange String-Variable, bleibt der Zeiger solange gültig, bis ein neuer Wert zur Variablen zugewiesen wird oder bis die Variable den Gültigkeitsberieich verläßt.

Während es möglich ist, eine Zeichenposition zuzuweisen, die durch das Indizieren eines langen Strings ermittelt wird, ist es nicht möglich so ein Zeichen als var-Parameter zu übergeben.

Wenn Sie lange String-Felder in einem Record deklarieren, müssen all diese Felder im nicht-varianten Teil des Records verbleiben. Mit anderen Worten, lange String-Felder eines Typs, der lange Strings enthält, sind nicht im varianten Teil eines Records erlaubt.

Wenn zum Ändern eines Werts eines einzelnen Zeichens in einer langen String-Variablen die Indizierung verwendet wird, wird erst eine Kopie des String-Werts erstellt, wenn die Referenz zur String-Wert-Referenzzahl größer als eins ist. Dies ist als Kopie-beim-Semantik-Schreiben bekannt, und garantiert, daß die Veränderungen nicht auch andere lange String-Variablen ändern, die sich auf den String-Wert beziehen.

Lange String-Variablen werden immer so initialisiert, daß sie bei der ersten Erstellung leer sind. Das gilt gleichwohl für globale, und lokale String-Variablen sowie String-Variablen, die Teil einer Struktur sind.

Wenn lange String-Variablen den Gültigkeitsbereich verlassen (wie beim Verlassen einer Funktion mit lokalen langen String-Variablen), wird der Referenzzähler ihrer Werte automatisch dekrementiert. Dies gilt für eine Funktion auch denn, wenn sie aufgrund einer Exception verlassen wird.

Lange String-Variablen werden immer so initialisiert, daß sie bei der ersten Erstellung leer sind. Das gilt gleichwohl für globale, und lokale String-Variablen sowie String-Variablen, die Teil einer Struktur sind.

Sie können eine nicht leere lange String-Variable mit einer einfachen Index-Anweisung indizieren, deren Wert im Bereich 1..N liegen muß, wobei N die dynamische Länge des langen Strings darstellt. Der Zeichentyp, auf den durch die Indizierung eines langen String zugegriffen wird ist ein Char. Der Index des ersten Zeichens in einem langen String ist 1. Anders als bei kurzen Strings haben die langen Strings keine nulltes Element, das die dynamische String-Länge enthält. Um die Länge eines langen Strings zu ermitteln, müssen Sie die Standardfunktion Length verwenden. Um die Länge eines langen Strings zu setzen, müssen Sie die Standardprozedur SetLength verwenden.


Siehe auch

Stringtypen

Kurze Stringtypen

String (rRserviertes Wort)

Null-terminierte Strings


Strings verwenden

Siehe auch	Stringtypen

Die Reihenfolge bei jeweils zwei String-Werten wird durch das Anordnungsverhältnis der Zeichenwerte auf entsprechenden Positionen definiert. Bei zwei Strings ungleicher Länge trägt jedes Zeichen des lägeren String, für das es kein entsprechendes Zeichen im kürzeren String gibt, ein Größer-als-Zeichen. 'BA' ist z. B. größer als 'A'. Nullängen-Strings sind nur mit anderen Nullängen-Strings gleich und sie heben die wenigsten String-Werte.

Operatoren für die String-Typen werden unter "String-Operatoren" und "Relationale Operatoren" in Kapitel 5 beschrieben.

Es ist möglich, in Ausdrücken und Zuweisungen kurze und lange Strings zu mischen, aber Strings mit var-Parametern müssen vom passenden Typ sein. Es ist mit anderen Worten nicht möglich, einen kurzen String als einen var-Parameter durch eine Prozedur oder Funktion laufen zu lassen, die einen langen String erwartet oder umgekehrt.

Ein kurzer String kann durch eine Zeichenfolge der Form AnsiString(S) explizit in einen langen String umgewandelt werden, wobei S ein Ausdruck eines kurzen Strings ist. Im Standardzustand {$H+} kann eine Zeichenfolge der Form string(S) ebenfalls einen kurzen String-Ausdruck in einen langen umwandeln.

Ein langer String kann durch eine Zeichenfolge der Form ShortString(S) explizit in einen kurzen String umgewandelt werden, wobei S der Ausdruck des langen Strings ist. Im Zustand {$H–} kann eine Zeichenfolge der Form string(S) ebenfalls einen langen Stringausdruck in einen kurzen umwandeln.


Siehe auch

Lange Stringtypen

Kurze Stringtypen

String (Reserviertes Wort)


Strukturierte Typen

Siehe auch	Typen

Ein strukturierter Typ enthält mehr als einen Wert. Die Komponenten von strukturierten Typen können einzeln oder in ihrer Gesamtheit manipuliert werden. Sie können selber wieder strukturierte Typen sein. Es gibt keine Beschränkung hinsichtlich der Anzahl solcher geschachtelter Strukturen.

Die strukturierten Typen in Object Pascal sind:

Arraytypen

Dateitypen

Klassentypen

Klassenreferenztypen

Recordtypen

Mengentypen

Ein strukturierter Typ kann geschachtelte Ebenen enthalten.

Klassentypen und Klassenreferenztypen sind die Eckpfeiler des objektorientierten Programmierens in Object Pascal.

Das reservierte Wort packed in der Deklaration eines strukturierten Datentyps teilt dem Compiler mit, die Datenspeicherung zu komprimieren, selbst wenn die Zugriffsmöglichkeitenauf eine Komponente einer Variable dieses Typs vermindert werden. Standardmäßig werden die Komponenten strukturierter Datentypen zum Zwecke des schnelleren Zugriffs in Wort- oder Doppelwort-grenzen ausgerichtet. Das Hinzufügen von packed zur Deklaration eines strukturierten Datentyps verhindert derartige Ausrichtung für diesen Typ.


Siehe auch

Strukturierte Typkonstanten

Kompatibilität der Datentypen


Array-Typen

Siehe auch	Beispiel	Structurierte Typen

Arrays sind ein- oder mehrdimensionale Bereiche, die viele Variablen des gleichen Typs enthalten. Auf jede Variable im Array kann über den Namen des Arrays und den Index der Variable zugegriffen werden, der in Klammern angegeben wird.

Um einen Arraytyp zu spezifizieren, benötigt der Compiler zwei Informationen:

den ordinalen Indextyp eines Arrays, der die Anzahl der Elemente angibt.

den Basistyp.

Die Anzahl der Elemente in einem Array ist das Produkt der Anzahl der Werte in jedem Indextypen.

Um auf Elemente des Arrays zuzugreifen, fügen Sie dem Arraybezeichner eckige Klammern und einen Indexwert hinzu. Die folgende Anweisung greift auf das dritte Element im Array zu:

array[3];

Verwenden Sie die Standardfunktionen Low und High in Verbindung mit einem Bezeichner vom Typ Array oder einer Variablenreferenz eines Arraytyps, um die oberen und unteren Indexgrenzen des Indextyps zurückzuliefern.

Mehrdimensionale Arraytypen

Wenn der Typ einer Arraykomponente auch ein Array ist, können Sie das Ergebnis als ein Array von Arrays behandeln oder als ein einzelnes mehrdimensionales Array. Zum Beispiel:

array[Boolean] of array[1..10] of array[Size] of Real

wird vom Compiler genauso interpretiert wie

array[Boolean,1..10,Size] of Real

Beim Deklarieren von mehrdimensionalen Arrays ist die Gesamtanzahl der Elemente das Produkt der Anzahl der Werte eines jeden Indextyps.

Nullbasierte Arrays

Nullbasierte Arrays werden deklariert, indem dem ersten Element in der Deklaration des Arrays der Index Null zugewiesen wird. Zum Beispiel:

array[0..5] of Char

Verwenden Sie nullbasierte Arrays, um nullterminierte Strings zu speichern. Ein nullbasiertes Array ist kompatibel zu einem Wert vom Typ PChar.


Beispiel für ein Array

Die Deklaration

array[1..100] of Real   { deklariert ein Array, das 100 Elemente vom Typ Real speichern kann }


Siehe auch

Array (Reserviertes Wort)

Arraytyp-Konstanten

Indizes

Nullterminierte Strings

Offene Array-Parameter

Kompatibilität der Datentypen

Variablenreferenz


Record-Typen

Siehe auch	Beispiel	Struktrierte Typen

Ein Recordtyp ist eine Anordnung von Feldern, die verschiedene Typen haben können.

Der Feldname und der Feldtyp müssen in der Deklaration des Recordtyps zugewiesen werden.

Der feste Teil eines Recordtyps legt die Liste der statischen Datenfelder mit jeweils einem Bezeichner und einem Typ fest. Jedes Feld enthält Informationen, die immer auf die gleiche Art und Weise gewonnen werden.

Der variante Teil eines Recordtyps verteilt den Speicherplatz für mehr als eine Liste von Feldern. Damit können Sie auf Information in mehr als einer Art zugreifen.

Jede Feldliste ist eine Variante, die den gleichen Platz im Speicher belegt. Jede Variante wird mit einer Konstanten unterschieden. Sie können jederzeit auf alle Felder aller Varianten zugreifen.

Jede Variante wird von mindestens einer Konstanten bezeichnet. Alle Konstanten müssen eindeutig und von ordinalem Typ sein, der kompatibel mit dem Typ des Markierungsfelds ist.

Der wahlfreie Bezeichner des Markierungsfelds ist der Bezeichner für ein zusätzliches festes Feld --das Markierungsfeld-- des Records. Das Programm verwendet den Wert des Markierungsfelds, um die aktive Variante anzuzeigen.

Ohne Markierungsfeld wählt das Programm eine Variante mit Hilfe eines anderen Kriteriums aus.

Hinweis:	Felder im varianten Teil eines Records können kein langer- oder varianter- Stringtyp sein. Genauso können Felder in varianten Teilen eines Records nicht vom strukurierten Typ sein, der lange oder variante Stringkomponenten enthält.

Zugriff auf Records

Sie können auf den ganzen Record oder auf jedes Feld einzeln zugreifen. Um auf ein einzelnes Feld zuzugreifen, schreiben Sie den Namen des Records, einen Punkt und dann den Feldbezeichner. Zum Beispiel:

TDateRec.Year

Um auf einen ganzen Record zuzugreifen, verwenden Sie die with-Anweisung.


Siehe auch

Gültigkeitsbereich von Records

Kompatibilität der Datentypen

With-Anweisung


Beispiele für Recordtypen

type

  TDateRec = record

    Year: Integer;

    Month: 1..12;

    Day: 1..31;

  end;

type

  TPerson = record

    FirstName, LastName: string[40];

    BirthDate: TDate;

    case Citizen: Boolean of

      True: (BirthPlace: string[40]);

      False: (Country: string[20];

        EntryPort: string[20];

        EntryDate: TDate;

        ExitDate: TDate);

  end;


Klassentypen

Siehe auch	Beispiel	Strukturierte Typen

Ein Klassentyp ist eine Struktur, die aus einer festen Anzahl von Komponenten besteht.

Mögliche Komponenten von Klassen sind:

Felder

Methoden

Eigenschaften

Im Gegensatz zu anderen Typen kann ein Klassentyp nur im Deklarationsteil des äußersten Gültigkeitsbereich eines Programms oder einer Unit deklariert werden. Deshalb kann ein Klassentyp nicht in einem Deklarationsteil einer Variable oder innerhalb einer Prozedur, Funktion oder eines Methodenblocks deklariert werden.

Ein Klassentyp wird mit dem reservierten Wort class deklariert und definiert den Inhalt einer Klasse.

Klasses werden auch "Objekttypen" genannt. die beiden Begriffe sind austauschbar.

Sie müssen einen Klassentyp global deklarieren. Ein Klassentyp kann nicht im Deklarationsteil einer Variable oder innerhalb einer Prozedur, Funktion oder eines Methodenblocks deklariert werden.

Der Komponententyp einer Datei kann weder ein Klassentyp sein, noch ein beliebiger strukturierter Typ mit einer Komponente vom Typ Klasse.

Vererbung

Ein Objekttyp kann Komponenten von einem anderen Klssentyp erben. Die erbende Klasse ist ein Nachkomme, die vererbende Klasse ist ein Vorfahr.

Vererbung ist transitiv, wenn z.B. T3 von T2 erbt und T2 von T1 erbt, dann erbt T3 auch von T1. Der Bereich eines Klassentyps erstreckt sich über den Klassentyp selbst und alle seine Nachkommen.

Eine Nachkommenklasse enthält implizit alle Komponenten, die von ihren Vorfahrenklassen definiert worden sind. Eine Nachkommenklasse kann zu den geerbten Komponenten neue hinzufügen, aber sie kann die Definition einer Komponente in einer Vorfahrenklasse nicht rückgängig machen.

Der vordefinierte Klssentyptyp TObject ist der oberste Vorfahr aller Klassentypen. Wenn die Deklaration eines Klassentyps keinen Vorfahrentypen spezifiziert (d.h. der Vererbungsteil in der Deklaration der Klasse wurde ausgelassen), wird der Klassentyp von Tobject abgeleitet. TObject ist in der System-Unit deklariert und definiert eine Anzahl von Methoden, die auf alle Klassen angewendet werden.

Typkompatibilität von Klassen

Ein Klassentyp ist zuweisungskompatibel mit jedem beliebigen Vorfahrenklassentypen. Deshalb kann während der Programmausführung eine Klssentypvariable eine Instanz dieses Typs oder eine Instanz eines beliebigen abgeleiteten Typs referenzieren. Gegeben seien, z.B. folgende Deklarationen:

type

  TFigure = class

    :

  end;

  TRectangle = class(TFigure)

    :

  end;

  TRoundRect = class(TRectangle)

    :

  end;

  TEllipse = class(TFigure)

    :

  end;

Ein Wert vom Typ TRectangle kann den Variablen vom Typ TRectangle, TFigure und TObject zugewiesen werden. Während der Programmausführung kann eine Variable vom Typ TFigure entweder nil sein oder eine Instanz von TFigure, TRectangle, TRoundRect, TEllipse oder jede andere Instanz einer Ableitung von TFigure referenzieren.


Siehe auch

Class (reserviertes Wort)

Gültigkeitsbereich von Komponenten

Sichtbarkeit von Komponenten

Instanziieren von Objekten

Methoden


Beispiel für einen Klassentyp

  TField = class

  private

    X, Y, Len: Integer;

    FName: String;

  public

    constructor Copy(F: TField);

    constructor Create(FX, FY, FLen: Integer; FName: String);

    destructor destroy; override;

    procedure Display; virtual;

    procedure Edit; dynamic;

  protected

    function GetStr: String; virtual;

    function PutStr(S: String): Boolean; virtual;

  private

    procedure DisplayStr(X, Y: Integer; S: String);

  public

    property Name: String read GetStr write Buffer;

  end;

  TStrField = class(TField)

  private

    Value: PString;

  public

    constructor Create(FX, FY, FLen: Integer; FName: String);

    destructor Destroy; override;

  protected

    function GetStr: String; override;

    function PutStr(S: String): Boolean; override;

  end;

  TNumField = class(TField)

  private

    Value, Min, Max: Longint;

  public

    constructor Create(FX, FY, FLen: Integer; FName: String;

      FMin, FMax: Longint);

    function GetStr: String; override;

    function PutStr(S: String): Boolean; override;

    function Get: Longint;

    procedure Put(N: Longint);

  end;


Methoden

Siehe auch	Klassentypen

Eine Methode ist eine Prozedur oder Funktion, die in der Deklaration eines Objekttyps deklariert wird.

Methoden die in einem Objekttyp deklariert sind, sind von der Standardeinstellung her statisch. Wenn eine Methode statisch ist, bestimmt der deklarierte Typ (zur Compile-Zeit) der Klasse oder des Objekts welche implementierte Methode aktiviert wird.

Methoden können auf die Datenfelder eines Objekts zugreifen, ohne daß diese als Parameter an die Methoden übergeben werden.

Die Deklaration der Methode in der Deklaration des Objekttyps besteht nur aus dem Methodenkopf und ist eine Vorwärts-Deklaration.

Der Rumpf der Methode wird außerhalb der Deklaration des Objekttyps, aber innerhalb des gleichen Gültigkeitsbereichs definiert. Der Methodenkopf muß den Namen des Objekttyps enthalten, auf den die Methode beschränkt ist:

  procedure ObjectType.Methode(Param1, Param2: Integer);

  begin

  ...

  end;  (* Methode *)

Per Voreinstellung sind Methoden statisch. Sie können aber auch zu einem der folgenden Typen gehören:

Virtuelle Methoden

Klassenmethoden

Konstruktoren und Destruktoren sind spezielle Methoden, die die Konstruktion und Destruktion von Objekten steuern.

Innerhalb einer Methode, eines Funktionsaufrufs oder einer Prozeduranweisung kann eine bestimmte Methode mit einem qualifizierten Methodenbezeichner aufgerufen werden. Dieser Aufruf wird qualifizierter Methodenaufruf genannt.


Siehe auch

Konstruktoren und Destruktoren

Methodenaufrufe

Methodendeklarationen

Objekttypen

Qualifizierte Methodenaktivierung

Self


Methoden-Implementation

Beispiel

Die Deklaration einer Methode innerhalb eines Objekttyps korrespondiert mit der forward Deklaration der Methode. Irgendwo nach der Objekttyp Deklaration, und innerhalb des gleichen Moduls, muß die Methode von einer definierten Deklaration implementiert werden.

Für Methoden von Prozeduren und Funktionen nimmt die definierte Deklaration die Form einer normalen Prozedur- oder Funktionsdeklaration. Mit der Ausnahme, daß die Prozedur oder Funktions Bezeichner im Kopfteil einen qualifizierten Methodenidentifizierer haben.

Für Konstruktoren und Destruktoren nimmt die definierte Deklaration die Form einer Prozedur Methoden Deklaration an. Mit der Ausnahme,daß das reservierte Wort procedure ersetzt wird durch Konstruktor oder Destruktor.

Eine definierte Deklaration einer Methode kann optional die formale Parameterliste eines Methodenkopfes in dem Klassentyp wiederholen. Die definierte Deklaration des Methodenkopfes muß genau mit der Reihenfolge, den Typen, und den NAmen der Parameter, und den Typen der Ergebnisfunktion übereinstimmen.

In der definierten Deklaration einer Methode gibt es immer einen impliziten Parameter mit dem Bezeichner Self, der mit den formalen Parametern des Klassentyps korrespondiert. Innerhalb des Methodenblocks repräsentiert Self die Instanz für die die Methode aktiviert wurde.

Der Gültigkeitsbereich eines Komponentenbezeichners in einem Objekttyp geht weiter als jeder Block einer Prozedur, Funktion, eines Konstruktors, oder Destruktors der eine Methode des Klassentyps implementiert hat.

Innerhalb eines Methodenblocks kann das reservierte Wort inherited dazu benutzt werden auf neudeklarierte oder überschriebene Bezeichner zuzugreifen. Wenn einem Bezeichner inherited vorausgeht, dann beginnt die Suche nach dem Bezeichner mit dem unmittelbaren Nachfahren der eingeschlossenen Methode des Objekttypen.


Beispiel

Gegeben ist die folgende Objekttyp Deklaration,

type

  TFramedLabel = class(TLabel)

  protected

    procedure Paint; override;

  end;

die Methode Paint muß später mithilfe einer definierten Deklaration implementiert werden, zum Beispiel,

procedure TFramedLabel.Paint;

begin

  inherited Paint;

  with Canvas do

  begin

    Brush.Color := clWindowText;

    Brush.Style := bsSolid;

    FrameRect(ClientRect);

  end;

end;


Virtuelle Methoden

Siehe auch	Beispiel

Der Compiler löst virtuelle Methoden zur Laufzeit auf. Dieser Vorgang wird als späte Bindung bezeichnet. Als Standard sind alle Methode statisch; Asunahmen sind die Konstruktormethoden. Sie können jede Methode virtuell deklarieren, indem Sie die Anweisung virtual in die Methodendeklaration schreiben.

Wenn eine virtuelle Methode aufgerufen wird, bestimmt der aktuelle(zur Laufzeit) Typ der klasse oder des Objekts die in der Methode benutz wird darüber welche Methodenimplementation aktiviert wird.

Jeder Objekttyp, der virtuelle Methoden deklariert oder erbt, muß auch mindestens eine Konstruktormethode deklarieren oder erben.

Überschreiben einer virtuellen Methode

Ein Objekttyp kann beliebige Methoden, die er von Vorfahren erbt überschreiben (neu definieren). Der Gültigkeitsbereich einer überschriebenen Methode erstreckt sich über alle Nachkommen des definierenden Objekts oder bis Sie den Methodenbezeichner neu definieren.

Eine virtuelle Methode wird überschrieben, wenn die Reihenfolge, die Typen und die Namen der Parameter und der Rückgabewert der Funktion, wenn vorhanden, übereinstimmen. Die überschriebene Methode muß auch wieder die Anweisung virtual enthalten.

Hinweis:	Der einzige Weg eine virtuelle Methode zu überschreiben geht über die Anweisung override. Wenn eine Methodendeklaration in einer abgeleiteten Klasse den gleiche Methodenidentifizierer spezifiziert, aber keine override Anweisung, dann wird die neue Methodendeklaration die ererbte Deklaration verstecken, sie aber nicht überschreiben.


Beispiel

Die folgenden zwei abgeleiteten Klassen überschreiben die Methode Draw die von TFigure geerbt wurde.

type

  TRectangle = class(TFigure)

    procedure Draw; override;

    :

  end;

  TEllipse = class(TFigure)

    procedure Draw; override;

    :

  end;

Der folgende Abschnitt illustriert den Effekt eines Aufrufs einer virutellen Methode über eine Variable eines Klassentyps dessen Typ zur Laufzeit variiert.

var

  Figure: TFigure;

begin

  Figure := TRectangle.Create;

  Figure.Draw;	{ Invokes TRectangle.Draw }

  Figure.Destroy;

  Figure := TEllipse.Create;

  Figure.Draw;	{ Invokes TEllipse.Draw }

  Figure.Destroy;

end;


Siehe auch

Methoden

Überschreibanweisung

Virtual (Standardanweisung)


Instantiieren von Objekten

Siehe auch

Eine Instanz eines Objekttyps ist ein dynamisch allokierter Speicherbereich mit einer internen Struktur, die vom Objekttyp definiert wird.

Instanzen eines Objekttyps werden auch allgemein als Objekte bezeichnet. Jedes Objekt eines Objekttyps besitzt eine eigene eindeutige Kopie der im Objekttyp deklarierten Felder, benutzt aber die Methoden mit anderen Objekten zusammen.

Eine Objekttypvariable enthält eine Referenz auf ein Objekt des Objekttyps. Die Variable enthält nicht das Objekt selbst, sondern ist bloß ein Zeiger auf den Speicherbereich, der für das Objekt allokiert wurde. Analog zu Zeigervariablen können sich mehrere Objekttypvariablen auf dasselbe Objekt beziehen. Eine Klassentypvariable kann den Wert nil enthalten, der angibt, daß sie momentan kein Objekt referenziert.

Hinweis:	Im Gegensatz zu Zeigervariablen ist es nicht notwendig, eine Objekttypvariable zu dereferenzieren, um Zugriff auf das referenzierte Objekt zu erhalten. Mit anderen Worten: wo es notwendig ist, Ptr^.Field zu schreiben, um auf ein Feld in einem dynamisch allokierten Record zuzugreifen, wird implizit der Operator ^ angenommen, wenn Sie auf eine Komponente eines Objekts zugreifen. Die Syntax ist einfach Instanz.Feld.


Siehe auch

Konstruktoren und Destruktoren

Methoden

Virtuelle Methoden


Methodenaufrufe

Siehe auch

Sie können eine Methode aufrufen, indem Sie eine Funktion oder Prozedur mit einer Anweisung aufrufen, die aus einem Methodenbezeichner und einer Liste der aktuellen Parameter besteht.

Die Variablenreferenz muß die Instanz eines Objekttyps sein. Ein Methodenbezeichner muß eine Methode dieses Objekttyps sein.

Der Methodenbezeichner wird zu einem impliziten aktuellen Parameter der Methode. Er entspricht einem formalen variablen Parameter Self, der den Objekttyp, entsprechend der aufgerufenen Methode, besitzt.

Bei einer with-Anweisung können Sie den Teil mit der Variablenreferenz eines Methodenbezeichners weglassen, weil diese den Parameter Self referenziert.

Innerhalb einer Methodendeklaration können Sie die Variablenreferenz weglassen. Der implizite Parameter Self des Methodenaufrufs wird zum Self der Methode, die den Aufruf enthält.


Siehe auch

Funktionsaufrufe

Methodendeklarationen

Parameter

Prozeduranweisungen

Qualifizierte Methodenaufrufe

With-Anweisung


Qualifizierte Methodenaufrufe

Siehe auch	Beispiel

Qualifizierte Methodenaufrufe verwenden einen Qualifizierer, um eine bestimmte Methode aufzurufen. Qualifizierte Methodenaufrufe können auftreten in:

einer Methode

einem Funktionsaufruf

einer Prozeduranweisung

Der Objekttyp in einem qualifizierten Methodenbezeichner muß denselben Objekttyp haben wie die einschließende Methode oder einer ihrer Vorfahren.

Verwenden Sie das reservierte Wort inherited, um den Vorfahren der einschließenden Methode zu spezifizieren. Sie können inherited nicht in Methoden eines Objekttyp verwenden, der keinen Vorfahren hat.

Der implizite Parameter Self eines qualifizierten Methodenaufrufs wird zum Self der Methode, die den Aufruf enthält.

Ein qualifizierter Methodenaufruf ist immer statisch und ruft immer die spezifizierte Methode auf.

Verwenden Sie qualifizierte Methodenaufrufe in einer override-Methode, um die überschriebene Methode aufzurufen.


Siehe auch

Funktionsaufrufe

Methodendeklarationen

Objekttypen

Prozeduranweisungen


Beispiele für qualifizierte Methodenaufrufe

Die folgenden Beispiele zeigen, wie es qualifizierte Methodenaufrufe ermöglichen, Code einer überschriebenen Methode in einer überschreibenden Methode zu verwenden.

constructor TShape.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  Width := 65;

  Height := 65;

  FPen := TPen.Create;

  FPen.OnChange := StyleChanged;

  FBrush := TBrush.Create;

  FBrush.OnChange := StyleChanged;

end;


Komponenten Sichtbarkeit

Siehe auch	Klassentypen

Die Sichtbarkeit von Komponenten wird gesteuert durch die Sichtbarkeitsattribute der Komponententeile in denen Bezeichner deklariert waren. Dafür gibt es fünf mögliche Sichtbarkeitsattribute:

published

public

protected

private

automated

Komponentenbezeichner die in der Komponentenliste, die unmittelbar dem Objekttypkopf folgt, deklariert sind, haben die published Sichtbarkeitsattribute wenn der Objekttyp mit dem Status {$M+} compiliert wurde, oder der Objekttyp von einer Klasse die mit dem Status {$M+} compiliert wurde. Ansonsten haben solche Komponentenbezeichner das public-Sichtbarkeitsattribut.


Siehe auch


Mengentypen

Siehe auch	Typen

Ein Mengentyp ist eine Ansammlung von Objekten vom gleichen ordinalen Typ. Um einen Mengentyp zu deklarieren, verwenden Sie die reservierten Wörter set of,  gefolgt vom Basistyp.

Der Wertebereich eines Mengentyps ist die Potenzmenge eines bestimmten ordinalen Typs (des Basistyps). Jeder mögliche Wert eines Mengentyp ist eine Untermenge der möglichen Werte des Basistyps.

Eine Mengentypvariable kann keinen oder alle Werte der Menge enthalten. Jeder Mengentyp kann den Wert [ ] enthalten, der leere Menge genannt wird.

Der Basistyp darf nicht mehr als 256 mögliche Werte haben. Die ordinalen Werte der Ober- und Untergrenze des Basistyps müssen im Bereich von 0 bis 255 liegen.

Vergleich von Mengen

Wenn A und B Mengenoperanden sind, ergeben die Vergleiche folgende Ergebnisse:

A = B ist nur dann True, wenn A und B genau die selben Elemente enthalten, ansonsten A <> B.

A <= B ist nur dann True, wenn jedes Element von A auch ein Element von B ist.

A >= B ist nur dann True, wenn jedes Element von B auch ein Element von A ist.

Feststellen der Mengenzugehörigkeit

Der Bezugsoperator in liefert True, wenn der Wert ein ordinaler Typ und ein Element des Mengentypoperanden ist, andernfalls liefert der Operator False.


Siehe auch

Ordinale Typen

Relationale Operatoren

Set (Reserviertes Wort)

Mengenoperatoren

Mengentypkonstanten

Kompatibilität der Datentypen


Dateitypen

Siehe auch	Typen

Ein Dateityp ist eine lineare Folge von Elementen eines beliebigen Typs. Es gelten die folgenden Ausnahmen:

Dateitypen

strukturierte Typen mit einer Dateityp-Komponente

Objekttypen

Die Anzahl der Elemente wird nicht von der Dateitypdeklaration festgelegt.

Wenn Sie das Wort of und den Typ in der Dateideklaration auslassen, ist die Datei eine untypisierte Datei.

Der Standarddateityp Text (oder Textdatei) stellt eine Datei mit Zeichen dar, die zeilenweise organisiert ist.


Siehe auch

File (Reserviertes Wort)

Kompatibilität der Datentypen


Kompatibilität der Datentypen

Siehe auch

Kompatibilität zwischen zwei Typen wird in Ausdrücken oder in relationalen Operationen gefordert. Kompatibilität der Datentypen ist eine Voraussetzung für Zuweisungskompatibilität.

Typen sind zueinander kompatibel, wenn mindestens eine der folgenden Bedingungen wahr ist:

Beide Typen sind gleich.

Beide Typen sind Realtypen.

Beide Typen sind Integertypen.

Ein Typ ist ein Unterbereich eines anderen.

Beide Typen sind Unterbereiche des gleichen Host-Typs.

Beide Typen sind Mengentypen mit kompatiblen Basistypen.

Beide Typen sind gepackte Stringtypen mit einer identischen Anzahl von Komponenten.

Ein Typ ist ein Stringtyp und der andere ist entweder ein Stringtyp, ein gepackter String oder vom Typ Char.

Ein Typ ist Pointer und der andere ist ein beliebiger Zeigertyp.

Beide Typen sind Klassentypen oder Klassenreferenztypen und ein Typ ist von dem anderen abgeleitet.

Ein Typ ist PChar und der andere ist ein nullbasiertes Zeichen-Array der Form array[0..X] of Char.

Beide Typen sind Zeiger auf identische Typen. (Dies gilt nur, wenn typgeprüfte Zeiger mit der Compiler-Anweisung  {$T+} aktiviert sind.)

Beide Typen sind prozedurale Typen mit identischen Typen der Rückgabewerte, einer identischen Anzahl von Parametern und einer eins-zu-eins-Gleichheit zwischen den Typen der Parameter.

Einer der Typen ist variant und der andere ist entweder ein Ganzzahltyp, Realtyp, Stringtyp oder Boolscher Typ.


Siehe auch

Zuweisungskompatibilität


Zuweisungskompatibilität

Siehe auch

Zuweisungskompatibilität ist notwendig, wenn etwas einen Wert zugewiesen bekommt, wie z.B. in einer Zuweisung oder bei der Übergabe von Parameterwerten.

Ein Objekttyp ist zuweisungskompatibel mit jedem Vorfahren-Objekttypen.

Ein Wert vom Typ T2 ist zuweisungskompatibel mit einem Typ T1 (das heißt: T1 := T2 ist erlaubt), wenn mindestens eine der folgenden Bedingungen wahr ist:

T1 und T2 sind identische Typen und weder ein Dateityp noch ein strukturierter Typ, der auf einer Strukturebene Komponenten vom Typ File enthält.

T1 und T2 sind kompatible ordinale Typen und die Werte vom Typ T2 fallen in den Bereich der möglichen Werte von T1.

T1 und T2 sind Realtypen und der Wert des Typs T2 fällt in den Bereich der möglichen Werte von T1.

T1 ist ein Realtyp und T2 ist ein Integertyp.

T1 und T2 sind Stringtypen.

T1 ist ein Stringtyp und T2 ist vom Typ Char.

T1 ist ein Stringtyp und T2 ist ein gepackter Stringtyp.

T1 ist ein langer Stringtyp und T2 vom Typ Char.

T1 und T2 sind kompatible gepackte Stringtypen.

T1 und T2 sind kompatible Mengentypen und alle Werte, die Elemente von T2 sind, fallen in den Bereich der möglichen Werte von T1.

T1 und T2 sind kompatible Zeigertypen.

T1 ist ein Klassentypund T2 ist ein Klassentyp, der von T1 abgeleited wurde.

T1 ist ein PChar und T2 ist eine String Konstante.

T1 ist ein PChar und T2 ist ein nullbasiertes Zeichen-Array der Form array[0..X] of Char.

T1 und T2 sind kompatible prozedurale Typen.

T1 ist ein prozeduraler Typ und T2 ist eine Prozedur oder Funktion mit einem identischen Rückgabewert, einer identischen Anzahl von Parametern und einer eins-zu-eins-Gleichheit der Parametertypen.

T1 ist Variant und T2 ist ein Intergertyp, Realtyp, Stringtyp oder Boolescher Typ.

T1 ist ein Intergertyp, Realtyp, Stringtyp oder Boolescher Typ und T2 ist Variant.

Ein Zeigertyp P2, der auf einen Objekttyp T2 zeigt, ist zuweisungskompatibel mit einem Zeigertyp P1, der auf einen Objekttyp T1 zeigt, wenn T2 im Bereich von T1 liegt.

Ein Fehler zur Compilezeit tritt auf, wenn Zuweisungskompatibilität erforderlich ist, aber keiner der Punkte in dieser Liste erfüllt ist.


Siehe auch

Kompatibilität der Datentypen


Klassenreferenztypen

Siehe auch	Beispiel	Objekttypen

Ein Klassenreferenztyp wird mit den reservierten Wörtern class of definiert, die vom Namen einer Klasse gefolgt werden. Eine Variable eines Objektreferenztyps kann zur Laufzeit gesetzt werden, um entweder auf die in der Deklaration genannte Klasse oder eine beliebige Unterklasse zu referenzieren.

Klassenreferenztypen sind in den folgenden Situationen hilfreich:

Mit einem virtuellen Constructor zum Erstellen eines Objekts, dessen tatsächlicher Typ bei der Kompilierung unbekannt ist

Mit einer Klassenmethode zum Durchführen einer Operation an einer Klasse, deren tatsächlicher Typ bei der Kompilierung unbekannt ist

Als richtiger Operand eines is-Operators zum Duchführen eines dynamischen Typen-Checks an einem Typ, der bei der Kompilierung unbekannt ist

Als richtiger Operand eines as-Operators zum Durchführen einer überprüften Zeichenfolge, deren Typ bei der Kompilierung nicht bekannt ist

Die Deklaration eines Klassenreferenz-Typs besteht aus dem reservierten Wort class of, gefolgt von einem Klassen-Typ-Bezeichner, z. B.:

type

  TComponent = class(TPersistent)

    :

  end;

  TComponentClass = class of TComponent;

  TControl = class(TComponent)

    :

  end;

  TControlClass = class of TControl;

var

  ComponentClass: TComponentClass;

  ControlClass: TControlClass;

Die vorigen Deklarationen definieren TComponentClass als Typ, der sich auf die Klasse TComponent beziehen kann, oder auf jede andere Klasse, die von TComponent und TControlClass abgeleitet wurde, die sich wiederum auf die Klasse TControl oder jede andere Klasse bezieht, die von TControl abgeleitet wurde.

Klassentyp-Bezeichner fungieren als Werte ihrer zugehörigen Klassenreferenz-Typen. Zusätzlich zu seinen anderen Verwendungen fungiert der  TComponent-Bezeichner beispielsweise als Wert des Typs TComponentClass und der TControl-Bezeichner fungiert als ein Wert des Typs TControlClass.

Ein Wert des Klassenreferenz-Typs ist zuweisungskompatibel mit jedem vorherigen Klassenreferenz-Typen. Während der Programmausführung kann sich eine Variable des Klassenreferenz-Typs die Klasse angeben, für die sie definiert wurde. Beim Bezug auf die vorigen Deklarationen sind die beiden Zuweisungen

ComponentClass := TComponent;      { Gültig }

ComponentClass := TControl;        { Gültig }

gültig. Von diesen Zuweisungen

ControlClass := TComponent;        { Ungültig }

ControlClass := TControl;          { Gültig }

Ist nur die zweite gültig. Die erste Zuweisung enthält einen Fehler, weil TComponent kein Abkömmling von TControl ist und deshalb kein Wert des typs TControlClass darstellt.

Eine Klassenreferenz-Typ-Variable kann nil sein, was anzeigt, daß sich die Variable gegenwärtig auf keine Klasse bezieht.

Jede Klasse erbt (von TObject) eine Methode namens ClassType, die einen bezug zu der Klasse eines Objekts herstellt. Der Typ des Werts, der von  ClassType geliefert wird, ist TClass, welche als class of TObject deklariert ist. as bedeutet, daß der Wert, der von ClassType geliefert wird, vielleicht eine Zeichenfolge eines nachfolgenden, spezifischeren Typs darstellt, z. B.

if Control <> nil then

  ControlClass := TControlClass(Control.ClassType) else

  ControlClass := nil;


Siehe auch

Klasse (Reserviertes Wort)


Beispiel

type

  {Eine Variable vom Typ TComponentRef kann zur Laufzeit gesetzt werden, um TComponentClass oder eine der Unterklassen zu referenzieren }

  TComponentRef = class of TComponentClass;

var

  TCRef: TComponentRef;

  NewComponent: TComponent;

...

TCRef := TButton; {TCRef kann nun überall für den Namen der Klasse TButton verwendet werden }

NewComponent := TCRef.Create; {TCRef wird hier verwendet, um ein neues TButton zu erzeugen }

...


Null-terminierte Strings

Siehe auch

Der Object Pascal-Compiler unterstützt eine Klasse von Zeichen-Strings, die man Null-terminierte Strings nennt. Null-terminierte Strings werden vielfach in den Programmiersprachen C and C++ eingesetzt, und von Windows selbst. Unter Verwendung von der Object Pascal-Unterstützung der Null-terminierten Strings und der Handling-Funktionen der Null-terminierten Strings, die von der Unit SysUtils geliefert werden, können Sie leicht mit anderen Sprachen und dem Windows-API interagieren.

Was ist ein null-terminierter String?

Ein null-terminierter String besteht aus einer Folge von Zeichen (nicht Null) gefolgt von NULL (#0). Anders als Strings bei Object Pascal besitzen Null-terminierte Strings keinen gesonderten Längenindikator. Stattdessen markiert die erste NULL in einem Null-terminierten String das Ende

Verwenden von null-terminierten Strings

Ein null-terminierter String wird als Array von Zeichen mit auf Null basierendem Integer-Indextyp gespeichert, z.B.:

array[0..X] of Char

wobei X = ein positiver Integerwert (nicht null).

Dies wird ein Null-basiertes Zeichen-Array genannt.

Null-terminierte Strings verwenden Character-Pointer mit

String-Literalen

Character-Arrays

Null-terminierte Strings und Standardprozeduren

Die folgenden Standardprozeduren können auf Null-basierte Arrays angewendet werden:

Read

Readln

Str

Val

Die folgenden Prozeduren können auch auf Character-Pointer angewandt werden:

Assign

Rename

Val

Write

WriteIn


Siehe auch

Stringtypen

Indizierung von Character-Pointern

Null-terminierte String-Funktionen

Mixing long strings and null-terminated strings

Null-terminated wide character strings


Character-Pointer und String-Literale

Siehe auch	Beispiel	Null-terminierte Strings

Ein String-Literal ist zuweisungskompatibel mit dem Typ Typ PChar. Dies bedeutet, daß ein String-Literal einer Variablen vom Typ PChar zugewiesen werden kann.

Der Effekt einer solchen Zuweisung ist der, daß der Pointer auf einen Speicherbereich zeigt, der eine Null-terminierte Kopie des String-Literals enthält.

Sie können String-Literals in Prozedur- und Funktionsaufrufen als aktuelle Parameter verwenden, wenn der entsprechende formale Parameter vom Typ PChar ist. Genauso wie bei einer Zuweisung erzeugt der Compiler eine Null-terminierte Kopie des String-Literals.

Sie können eine getypte Konstante vom Typ PChar mit einer String-Konstante initialisieren. Dies könne Sie auch mit strukturierten Typen, wie z.B. PChar-Arrays und Objekte bzw. Records mit PChar-Feldern.


Siehe auch

Character-Pointer und Character-Arrays

Indizierung von Character-Pointern

Null-terminierte Strings


Beispiel

var

  P: PChar;

begin

  P := 'Hallo Welt...';

end;


Character-Pointers und Character-Arrays

Siehe auch	Beispiel 	Null-terminierte Strings

Ein Null-terminiertes Array ist mit Typ Typ PChar kompatibel. Dies bedeutet, Sie in jedem Fall, in dem ein PChar erwartet wird, stattdessen ein Null-basiertes Character-Array verwenden können.

Falls Sie ein Character-Array anstelle eines PChar-Wertes verwenden, konvertiert der Compiler das Character-Array in eine Pointerkonstante, deren Wert mit der Adresse des ersten Array-Elements übereinstimmt.

Sie können eine getypte Konstante eines Null-basierten Character-Arrays mit einem String-Literal initialisieren, das kürzer als die deklarierte Länge des Arrays ist. Die übrigen Zeichen werden auf NULL (#0) gesetzt und somit enthält das Array einen Null-terminierten String.


Siehe auch

Character-Pointer und Character-Arrays

Indizierung von Character-Pointern

Null-terminierte Strings


Beispiel

var

  A: array[0..63] of Char;

  P: PChar;

begin

  P := A;       {P zeigt jetzt auf das erste Element von A}

  PrintStr(A);

  PrintStr(P);  {PrintStr wird zweimal mit demselben Wert aufgerufen}

end;


Indizierung von Character-Pointern

Siehe auch	Beispiel 	Null-terminierte Strings

Ein Character-Pointer kann wie ein Null-basiertes Array indiziert werden, da ein Null-basiertes Character-Array zu einem Character-Pointer kompatibel ist.

Wenn Sie einen Character-Pointer indizieren, stellt der Index einen Offset dar, der auf den Pointer addiert wird bevor dieser dereferenziert wird. Aus diesem Grunde gilt: P[0] = P^. P[0] spezifiziert das Zeichen, auf das P zeigt, P[1] spezifiziert das Zeichen direkt hinter demjenigen, auf das P zeigt, P[2] spezifiziert das nächste Zeichen usw.

Genauso bezeichnet P[-1] das Zeichen genau vor dem, auf das P zeigt usw.

Wenn ein Character-Pointer indiziert wird führt der Compiler keine Bereichsüberprüfung durch, da er keine Information hat, mit der er die maximale Länge des Null-terminierten String, auf den der Character-Pointer zeigt, hat. Ihr Programm muß solche Bereichsüberprüfungen selbst durchführen.


Beispiel

{Das folgende Beispiel verwendet die Indizierung von Character-Pointern, um einen Null-terminierten String in Großbuchstaben umzuwandeln.}

function StrUpper(Str: PChar): PChar;

var

  I: Integer;

begin

  I := 0;

  while Str[I] <> #0 do

  begin

    Str[I] := UpCase(Str[I]);

    Inc(I);

  end;

  StrUpper := Str;

end;


Siehe auch

PChar


Null-terminierte String-Funktionen

Null-terminierte Strings

Die Unit SysUtils bietet eine Anzahl von Null-treminierten String-Handling-Funktionen. Die fogende Tabell gibt eine kurze Beschreibung zu jeder dieser Funktionen.

Funktion	Beschreibung
StrAlloc	Teilt einem Stapel einen Zeichenpuffer gegebener Grüße zu..
StrBufSize	Liefert die Größe des zugewiesenen Zeichenpuffers unter Verwendung von StrAlloc oder StrNew.
StrCat	Verkettet zwei Strings.
StrComp	Vergleicht zwei Strings.
StrCopy	Kopiert einen String.
StrDispose	Ordnet einen Zeichenpuffer an, der mit StrAlloc oder StrNew zugewiesen wurde.
StrECopy	Kopiert einen String und liefert einen Pointer ans Ende des String.
StrEnd	Liefert einen Pointer ans Ende des String.
StrFmt	Formatiert einen oder mehrere Werte in einem String.
StrIComp	Vergleicht zwei Strings ohne Groß- und Kleinschreibung.
StrLCat	Verkettet zwei Strings mit gegebener Maximallänge zu einem reultierenden String.
StrLComp	Vergleicht zwei Strings mit einer gegebenen Maximallänge.
StrLCopy	Kopiert einen String bis zu einer gegebenen Maximallänge.
StrLen	Liefert die Länge eines Strings.
StrLFmt	Formatiert ein oder mehrere Werte in einem String mit einer gegebenen Maximallänge.
StrLIComp	Verbleicht zwei Strings mit einer gegebenen Maximallänge ohne Groß- und Kleinschreibung.
StrLower	Formt ein String in Kleinbuchstaben um.
StrMove	Verschiebt eine Zeichenblock von einem String zu einem anderen.
StrNew	Weist ein String einem Stapel zu.
StrPCopy	Kopiert einen Pascal-String zu einem Null-terminierten String.
StrPLCopy	Kopiert einen Pascal-String zu einem Null-terminierten String mit einer gegebenen Maximallänge.
StrPos	Liefert einen Pointer an das erste Auftreten eines Unterstrings innerhalb eines Strings.
StrRScan	Liefert einen Pointer an das letzte Auftreten eines gegebenen Zeichens innerhalb eines Strings..
StrScan	Liefert einen Pointer an das erste Auftreten eines gegebenen Zeichens innerhalb eines Strings.
StrUpper	Formt einen String in Großbuchstaben um.


Mischen von langen Strings und Null-terminierten Strings

Siehe auch	Null-terminierte strings

Object Pascal gestattet es,  lange un Null-terminierte Strings in Ausdrücken und Zuweisungen zu kombinieren. Die Regeln, die das Mischen von langenund Null-terminierten Strings kontrollieren, werden unten erläutert.

Ein Null-terminierter String ist Zuweisungskompatibel mit einem langen String. Mit anderen Worten kann ein Wert PChar einer Variablen vom Typ string zugewiesen oder werden, oder als Konstanten- oder Werteparametervom Typ string passiert werden. Die Zuweisung S := Pbeispielsweise, bei der S eine string-Variable und P einen PChar-Ausdruck darstellt, kopiert einen Null-terminierten String in einen langen String.

Wenn in einem Ausdruck ein Operand eines binären Operators vom Typ string ist, und der andere vom Typ PChar, wird der PChar-Operand automatisch in einen vom Typ string umgewandelt.

Eine Ausdruck der Form string(P), bei der P einen PChar-Ausdruck darstellt, kann verwendet werden, um einen Null-terminierten String in einen langen String umzuwandeln. Dieses ist in Situationen hilfreich, in denen beide Operanden eines Operators vom Typ PChar sind, Sie aber eine String-Operation durchführen wollen. Z. B. verkettet

S := string(P1) + string(P2);

zwei Null-terminierte Strings, um einen resultierenden langen String zu erhalten.

Ein Ausdruck der Form PChar(S), bei dem S einen langen String-Ausdruck darstellt, kann zum Umwandeln eines langen Strings in einen Null-treminierten String verwendet werden.


Siehe auch

Lange Stringtypen


Null-terminierte Weitzeichen-Strings

Siehe auch	Null-terminierte Strings

Das Betriebssystem Windows unterstützt drei Arten von Zeichensätzen:

Single-Byte-Zeichensätze

Double-Byte-Zeichensätze

Der Unicode-Zeichensatz

Single-Byte-Zeichen

Bei einem Single-Byte-Zeichensatz (single-byte character set, SBCS) ist ein String eine Abfolge von Bytes und jedes Byte stellt ein bestimmtes Zeichen dar.

Der  ANSI-Zeichensatz, der von den meisten westlichen Versionen von Windows verwendet wird, ist ein  character set used by most Western versions of Windows ist ein Single-Byte-Zeichensatz.

Double-Byte-Zeichen

Bei einem Double-Byte-Zeichensatz (double-byte character set, DBCS) ist ein String ebenfalls eine Abfolge von Bytes, aber im Unterschied zu Single-Byte-Zeichensätzen, werden einige Zeichen von einem und andere von zwei Bytes dargestellt.

Das erste Byte eines Zwei-Byte-Zeichens heißt Führungs-Byte.

Im Allgemeinen passen die ersten 128 Zeichen eines Double-Byte-Zeichensatzes zum 7-Bit ASCII-Zeichensatz und Führungs-Bytes besitzen Ordnungswerte, die grüßer oder gleich 128 sind.

Double-Byte-Zeichensätze sind in Asien verbreitet, wo die Zeichensätze der Landessprachen mehr als 256 Zeichen umfassen.

Unicode-Zeichen

Der Unicode-Zeichensatz unterscheidet sich grundlegend von Single- und Double-Byte-Zeichensätzen, in denen jedes Zeichen als Wort (zwei Bytes) dargestellt wird. Eine Zeichenkette im Unicode-Zeichensatz besteht aus einer Abfolge von Wörtern, nicht von Bytes.

Unicode-Zeichen sind als Weitzeichen bekannt, und Unicode-Strings als Weitzeichen-Strings.

Mit 65536 möglichen Wertenfür jedes Zeichen, kann Unicode alle Zeichen der Welt im modernen Computer-Einsatz darstellen, einschließlich technischer Symbole und Sonderzeichen, die für die Veröffentlichung verwendet werden.

Die ersten 256 Zeichen des Unicode-Zeichensatzespassen zum ANSI-Zeichensatz.

Object Pascal-Zeichensätze

Object Pascal unterstützt Single- und Double-Byte-Zeichensätze und Zeichen-Strings durch die AnsiChar-, PAnsiChar- und AnsiString -Fundamentaltypen, und die Char-, PChar-, and string-Generictypen. Weitzeichen werden durch die Typen WideChar und PWideCharunterstützt.

Es gibt zum string-Typ kein Weitzeichen-Äquivalent.

Strings aus Weitzeichen

The Null-terminierten String-Handling-Funktionen von Object Pascal lassen sich auch auf den PWideChar-Typ anwenden. das bedeutet, daß ein String-Literal Zuweisungskompatibel mit dem PWideChar-Typ ist (obwohl das String-Literal nur Weitzeichen mit Ordnungswerten im Bereich der ANSI-Zeichen enthalten kann). Auch ein Null-basierter Zeichen-Array der Form

array[0..X] of WideChar

ist Zuweisungskompatibel mit dem Typ PWideChar und ein Wert vom Typ PWideChar kann indiziert werden, als sei er ein Null-basierter Weitzeichen-Array. Weiterhin können die Char-Pointer-Operatoren (+ und –) auch auf Weitzeichen-Pointer angewendet werden.

Hinweis:	Beim Addieren oder Subtrahieren von ganzzahligen Offsets zu und von Weitzeichen-Pointern stellen die Offsets Entfernungen in Weitzeichen dar, und werden deshalb automatisch mit zwei multipliziert, bevor sie zu den Pointern addiert oder von ihnen subtrahiert werden. Genauso wird die resultierende Ganzzahl bei der Subtraktion eines Weitzeichen-Pointers von inem anderen automatisch durch zwei geteilt, um eine Entfernung in den Weitzeichenn zu erhaten.

The System-Unit bietet drei Funktionen, WideCharToString, WideCharLenToString und StringToWideChar, die zum Konvertieren von Null-terminierten Weitzeichen-Strings in Single- oder Double-Byte-Langzeichen-Strings verwendet werden können.


Siehe auch

Zeichentypen

Stringtypen

Null-terminierte String-Functionen


Variant-Typen

Siehe auch	Beispiele	Typen

Mit dem Typ Variant können Werte dargestellt werden, die ihren Typ dynamisch ändern. Während eine Variable eines beliebigen anderen Typs statisch an diesen Typ gebunden ist, kann eine Variable vom Typ Variant während der Laufzeit Werte verschiedener Typen annehmen. Der Typ Variant wird am häufigsten in Situationen eingesetzt, in denen der tatsächlich zu verarbeitende Typ entweder oft wechselt oder während der Compilierung noch unbekannt ist.

Der vordefinierte Bezeichner Variant kennzeichnet den Variantentyp. Varianten weisen die folgenden Merkmale auf:

Varianten können ganze oder reelle Zahlen, Stringwerte, Boolesche Werte, Datum-Uhrzeit-Werte sowie OLE-Automatisierungsobjekte enthalten. Außerdem können Varianten Arrays aufnehmen, deren Größe und Dimensionen wechseln und die Elemente eines der oben genannten Typen enthalten können.

Mit dem speziellen Variantenwert Unassigned wird angezeigt, daß einer Variante bislang noch keine Daten zugewiesen wurde, und mit dem speziellen Variantenwert Null werden unbekannte oder fehlende Daten gekennzeichnet.

Varianten können mit anderen Varianten, mit ganzen oder reellen Zahlen, mit Stringwerten und mit Booleschen Werten in Ausdrücken kombiniert werden, und der Compiler erzeugt automatisch Programmcode, der die notwendigen Typenkonvertierungen durchführt.

Wenn eine Variante ein OLE-Automatisierungsobjekt enthält, können mit der Variante die Eigenschaften des Objektes aufgerufen und gesetzt sowie Methoden für das Objekt aufgerufen werden.

Variantenvariablen werden bei ihrer Erstellung stets auf Unassigned initialisiert. Dies gilt immer, ganz gleich, ob eine Variantenvariable global, lokal oder Teil einer Struktur wie ein Array, ein Datensatz oder ein Objekt ist.

Beachten Sie, daß Varianten zwar eine größere Flexibilität als normale Variablen bieten, aber gleichzeitig mehr Speicher als diese belegen, und Operationen auf Varianten laufen beträchtlich langsamer ab als Operationen auf statisch typisierte Werte.


Beispiele für Variant-Typen

Im folgenden Ausschnitt aus einem Programmcode wird die Verwendung von Varianten und von einigen der automatischen Typenkonvertierungen demonstriert, die bei der Kombination von Varianten mit anderen Typen durchgeführt werden.

var

  V1, V2, V3, V4, V5: Variant;

  I: Integer;

  D: Double;

  S: string;

begin

  V1 := 1;	{ Ganze Zahl }

  V2 := 1234.5678;	{ Reelle Zahl }

  V3 := 'Hallo, Welt';	{ Stringwert }

  V4 := '1000';	{ Stringwert }

  V5 := V1 + V2 + V4;	{ Reelle Zahl 2235.5678 }

  I := V1;	{ I = 1 }

  D := V2;	{ D = 1234.5678 }

  S := V3;	{ S = 'Hallo, Welt' }

  I := V4;	{ I = 1000 }

  S := V5;	{ S = '2235.5678' }

end;


Siehe auch

Werte in Varianten

Variantentypkonvertierungen

Variantenausdrücke

Varianten-Arrays

Varianten und OLE-Automatisierungsobjekte


Werte in Varianten

Variant-Typen

Eine Variable vom Typ Variant belegt 16 Bytes Speicherplatz, und ihre interne Darstellung besteht aus einem Typencode und einem Wert (oder einem Bezug auf einen Wert) von dem durch den Typencode angegebenen Typ. Die Standard-Eigenschaft VarType gibt den Typencode einer Variante zurück. In der folgenden Tabelle werden die Konstanten und die Werte von Variantentypen zusammen mit der Bedeutung der Typencodes aufgeführt.

VarType	Wert	Inhalt der Variante
varEmpty	$0000	Die Variante ist Unassigned. Der Variante wurde kein Wert zugewiesen; daher wird Null angenommen. In einem Ausdruck wird VarEmpty auf einen Nullwert oder einen leeren String gesetzt.
varNull	$0001	Die Variante ist Null. Der Variante wurde kein Wert zugewiesen. Ein Ausdruck, der eine VarNull-Variante enthält und eine zugewiesene Ariante, wird zu VarNull ausgewertet. VarNull wird normalerweise dazu verwendet, fehlende Daten auszuweisen.
varSmallint	$0002	Ganze 16-Bit-Zahl mit Vorzeichen (Typ Smallint).
varInteger	$0003	Ganze 32-Bit-Zahl mit Vorzeichen (Typ Integer).
varSingle	$0004	Fließkommawert einfacher Genauigkeit (Typ Single).
varDouble	$0005	Fließkommawert doppelter Genauigkeit(Typ Double).
varCurrency	$0006	Fließkomma-Währungswert (Typ Currency). Die Variante enthält einen Währungswert (8-Byte-Festkommawert mit 4 Dezimalstellen).
varDate	$0007	Datum-Uhrzeit-Wert (Typ TDateTime).
varOleStr	$0008	Bezug auf einen OLE-String (ein dynamisch belegter Unicode-String). Die Variante enthält einen Zeiger auf einen null-terminierten String, der mit SysAllocStr zugewiesen wurde.
varDispatch	$0009	Bezug auf ein OLE-Automatisierungsobjekt (ein IDispatch-Schnittstellenzeiger).
varError	$000A	Betriebssystemfehlercode.
varBoolean	$000B	Boolescher 16-Bit-Wert (Typ WordBool).
varVariant	$000C	Variante (Verwendung nur mit Varianten-Arrays).
varUnknown	$000D	Bezug auf ein unbekanntes OLE-Objekt (ein IUnknown-Schnittstellenzeiger). Die Variante enthält unbestimmte oder benutzerdefinierte Daten.
varByte	$0011	Vorzeichenlose ganze 8-Bit-Zahl (Typ Byte).
varString	$0100	Bezug auf einen dynamisch belegten langen String (Typ AnsiString).
varTypeMask	$0FFF	Bitmaske für die Extrahierung von Typencode. Diese Konstante ist eine Maske, die mit dem Feld VType über ein bitweises AND verbunden werden kann.
varArray	$2000	Bit zur Kennzeichnung eines Variantenarrays. Diese Konstante ist eine Maske, die mit dem Feld VType über ein bitweises AND verbunden werden kann, um zu bestimmen, ob die Variante einen einzelnen Wert oder einen Werte-Array enthält.
varByRef	$4000	Diese Konstante kann über AND mit der Variante VType verbunden werden, um festzustellen, ob die Variante einen Zeiger auf die angegebenen Daten anstelle der Daten selbst enthält.

Die von der Standard-Eigenschaft VarType zurückgegebenen Konstanten varXXXX sind in der System-Unit definiert. Beachten Sie, daß in zukünftigen Versionen von Object Pascal möglicherweise zusätzliche Typencodes definiert sind; achten Sie also sorgfältig darauf, keinen Programmcode zu schreiben, der nur diese Codes als Rückgabewerte akzeptiert.

Die Bitposition varArray wird gesetzt, wenn die Variante ein Array des angegebenen Typs enthält. Mit der Bitmaske varTypeMask wird der eigentliche Typencode aus einem von der Funktion VarType zurückgegebenen Wert extrahiert. Der folgende Ausdruck ist beispielsweise True, wenn V ein Double oder ein Array von Double enthält:

if VarType(V) and varTypeMask = varDouble then ...

Der in der Systemeinheit definierte TVarData-Datensatz kann für die Typumwandlung einer Variant-Variable verwendet werden, um so Zugriff auf ihre interne Darstellung zu erhalten. Weitere Einzelheiten finden Sie in der Beschreibung von TVarData im Handbuch Visual Component Library Reference.


Variantentypkonvertierungen

Siehe auch	Variant-Typen

Die Typen Integer, Real, String, Character und Boolean sind mit dem Typ Variant zuweisungskompatibel. In der folgenden Tabelle sind die Typen aufgeführt, die zu Variant zugewiesen werden können, zusammen mit den sich ergebenden Variantentypencodes.

Ausdruckstyp	Variantentypencode
ganze Zahlen	varInteger
reelle Zahlen außer Währung	varDouble
Währung	varCurrency
String und Zeichen	varString
Boolescher Typ	varBoolean

Ein Ausdruck kann mit Hilfe einer Typumwandlung der Form Variant(X) explizit in den Typ Variant umgewandelt werden, wobei X ein Ausdruck von einem der in der obigen Tabelle aufgeführten Typen ist.

Der Typ Variant ist zuweisungskompatibel mit den Typen Integer, Real, String und Boolean. In den folgenden Tabellen werden die Regeln für die Typenkonvertierung aufgeführt, nach denen die Konvertierung von Variant-Werten in andere Typen abläuft.

Konvertierung einer Variante in einen Wert vom Typ Integer

Variantentyp	Ergebnis
varEmpty	0.
varNull	Löst eine EVariantError-Ausnahme aus.
varByte varSmallint varInteger varError	Konvertiert ein Integer-Format in ein anderes Integer-Format, löst eine EVariantError-Ausnahme aus, wenn der Wert nicht in das Zielformat paßt.
varSingle varDouble varCurrency	Rundet eine reelle Zahl auf die am nächsten liegende ganze Zahl, löst eine EVariantError-Ausnahme aus, wenn das Ergebnis nicht in das Zielformat paßt.
varDate	Interpretiert Datum-Uhrzeit-Werte als Double, rundet den Wert auf die am nächsten liegende ganze Zahl, löst eine EVariantError-Ausnahme aus, wenn das Ergebnis nicht in das Zielformat paßt.
varOleStr varString	Konvertiert String in Integer, löst eine EVariantError-Ausnahme aus, wenn der String kein gültiger Integer-Wert ist oder das Ergebnis nicht in das Zielformat paßt.
varBoolean	0 für False, -1 für True (255, wenn Byte der Zieltyp ist).
Konvertierung einer Variante in einen Wert vom Typ Real

Variantentype	Ergebnis
varEmpty	0.
varNull	Löst eine EVariantError-Ausnahme aus.
varByte varSmallint varInteger varError	Konvertiert eine ganze Zahl in eine reelle Zahl.
varSingle varDouble varCurrency	Konvertiert von einem Real-Format in ein anderes Real-Format, löst eine EVariantError-Ausnahme aus, wenn der Wert nicht in das Zielformat paßt.
varDate	Interpretiert den Wert als Double, rundet den Wert auf die am nächsten liegende ganze Zahl, löst eine EVariantError-Ausnahme aus, wenn das Ergebnis nicht in das Zielformat paßt.
varOleStr varString	Konvertiert einen String mit Regional Settings im Windows Control Panel in eine ganze Zahl, löst eine EVariantError-Ausnahme aus, wenn der String kein gültiger Real-Wert ist oder das Ergebnis nicht in das Zielformat paßt.
varBoolean	0 für False, -1 für True.
Konvertierung einer Variante in einen Datum-Uhrzeit-Wert

Variantentyp	Ergebnis
varEmpty	30.12.1899, 12:00 mittags.
varNull	Löst eine Ausnahme aus.
varByte varSmallint varInteger varError	Konvertiert Integer in Double, interpretiert das Ergebnis als Datum-Uhrzeit-Wert.
varSingle varDouble varCurrency	Konvertiert den Wert in Double, interpretiert das Ergebnis als Datum-Uhrzeit-Wert.
varDate	Keine Translation.
varOleStr varString	Konvertiert einen String mit Regional Settings im Windows Control Panel in einen Datum-Uhrzeit-Wert.
varBoolean	Konvertiert Boolean in Double, interpretiert das Ergebnis als Datum-Uhrzeit-Wert.
Konvertierung einer Variante in einen Wert vom Typ String

Variantentyp	Ergebnis
varEmpty	Leerer String.
varNull	Löst eine Ausnahme aus.
varByte varSmallint varInteger varError	Konvertiert einen Integer-Wert in eine String-Darstellung.
varSingle varDouble varCurrency	Konvertiert einen Real-Wert mit Regional Settings im Windows Control Panel in eine String-Darstellung.
varDate	Konvertiert Datum-Uhrzeit-Wert mit Regional Settings im Windows Control Panel in eine String-Darstellung.
varOleStr	Konvertiert von Unicode in ANSI, wenn varString der Zieltyp ist.
varString	Konvertiert von ANSI in Unicode, wenn varOleStr der Zieltyp ist.
varBoolean	'0' für True, '-1' für False.
Konvertierung einer Variante in einen Wert vom Typ Boolean

Variantentyp	Ergebnis
varEmpty	False.
varNull	Löst eine Ausnahme aus.
varByte varSmallint varInteger varError	False, wenn der Wert gleich Null ist, True für einen Wert ungleich Null.
varSingle varDouble varCurrency	False, wenn der Wert gleich Null ist, True für einen Wert ungleich Null.
varDate	Interpretiert den Wert als Double, gibt False zurück, wenn der Wert gleich Null ist und True, wenn der Wert ungleich Null ist.
varOleStr varString	False, wenn der String 'false' enthält (unabhängig von Groß- und Kleinschreibung) oder wenn das Ergebnis eines numerischen Strings gleich Null ist, True, wenn der String 'true' enthält (unabhängig von Groß- und Kleinschreibung) oder wenn das Ergebnis eines numerischen Strings ungleich Null ist, ansonsten wird eine EVariantError-Ausnahme ausgelöst.
varBoolean	Keine Translation.

Ein Variant-Wert kann mit Hilfe einer Typumwandlung der Form TypeName(V) explizit in den Typ Integer, Real, String und Boolean umgewandelt werden, wobei TypeName ein Typbezeichner für Integer, Real, String oder Boolean ist und V einem Ausdruck vom Typ Variant entspricht. Außerdem können die Standard-Funktion VarAsType und die Standard-Prozedur VarCast für die Veränderung der internen Darstellung einer Variante benutzt werden. In den obigen Tabellen sind die Regeln aufgeführt, nach denen alle solchen Typkonvertierungen ablaufen.

Wenn eine Variante einen Bezug auf ein OLE-Automatisierungsobjekt enthält (Typencode varDispatch), wird bei jedem Versuch, die Variante in einen anderen Typ zu konvertieren, zuerst der Wert der Standard-Eigenschaft des Objekts abgerufen und dieser Wert anschließend in den gewünschten Typ umgewandelt. Wenn das angegebene OLE-Automatisierungsobjekt keine Standard-Eigenschaft besitzt, wird eine EVariantError-Ausnahme ausgelöst.


Siehe auch

Werte in Varianten

Variantenausdrücke


Variantenausdrücke

Siehe auch	Variant-Typen

Varianten können in Ausdrücken auftreten. Die folgenden Operatoren unterstützen Operanden vom Typ Variant:

    +   –   *   /   div   mod   shl   shr   and   or   xor   not   =   <>   <   >   <=   >=

Für Operatoren, die zwei Operanden annehmen, gilt: Wenn einer der Operanden vom Typ Variant ist, wird der andere Operand automatisch in den Typ Variant umgewandelt; dies geschieht gemäß den Regeln im Abschnitt Variantentypkonvertierungen. Der Ergebnistyp einer nichtrelationalen Operation (alle oben aufgeführten Operatoren mit Ausnahme der letzten sechs) auf Variant-Werte ist immer Variant. Der Ergebnistyp einer relationalen Operation auf Variant-Werte ist immer Boolean.

Für alle nichtrelationalen Operatoren gilt: Wenn einer oder beide Operanden Unassigned sind, wird eine EVariantError-Ausnahme ausgelöst. In anderen Worten: Für Unassigned-Varianten sind ausschließlich Vergleichsoperationen zulässig.

Für alle nichtrelationalen Operatoren gilt außerdem: Wenn einer oder beide Operanden Null ist, ist das Ergebnis der Operation Null. In anderen Worten: Null-Werte werden durch Ausdrücke hindurch weitergegeben, und das Auftreten eines Null-Wertes in einem Ausdruck führt dazu, daß der gesamte Ausdruck Null wird.

Bei der Durchführung einer Operation mit zwei Operanden regelt der den beiden Variant-Operanden gemeinsame Typ die Operation. Der gemeinsame Typ wird mit Hilfe der in der nachstehenden Tabelle aufgeführten Matrix bestimmt. Für die Variantentypencodes varSmallint, varInteger und varByte wird ein Mapping auf Integer durchgeführt, für varSingle und varDouble auf Double und für varOleStr und varString auf String.

Typmatrix für Variantenoperationen

	Integer	Double	Currency	String	Boolean	Date
Integer	Integer	Double	Currency	Double	Integer	Date
Double	Double	Double	Currency	Double	Double	Date
Currency	Currency	Currency	Currency	Currency	Currency	Date
String	Double	Double	Currency	String	Boolean	Date
Boolean	Integer	Double	Currency	Boolean	Boolean	Date
Date	Date	Date	Date	Date	Date	Date

Für die Operation V1 + V2 gilt beispielsweise: Wenn der V1 vom Typ varInteger ist und V2 vom Typ varString, ist der gemeinsame Typ für die Durchführung der Operation Double.

Sobald bei nichtrelationalen Operatoren der gemeinsame Typ bestimmt ist, wird die Operation wie in der nachstehenden Tabelle beschrieben fortgesetzt.

Operatorergebnisse bei nichtrelationalen Varianten

Gemeinsamer Typ	Operatorergebnisse
Integer	Bei allen Operatoren mit Ausnahme von / werden die Operanden in Integer konvertiert, und der Ergebnistyp ist Integer; wenn das Ergebnis nicht in eine ganze 32-Bit-Zahl mit Vorzeichen paßt, ist er Double. Beim Operator / wird die Operation als Double-Operation durchgeführt.
Double	Bei den Operatoren +, –, * und / werden die Operanden in Double konvertiert, und der Ergebnistyp ist Double. Bei allen anderen Operatoren wird die Operation als Integer-Operation durchgeführt.
Currency	Bei den Operatoren +, –, * und / werden die Operanden in Currency konvertiert, und der Ergebnistyp ist Currency; bei einer Division von zwei Currency-Werten ist er Double. Bei allen anderen Operatoren wird die Operation als Integer-Operation durchgeführt.
String	Wenn beim Operator + beide Operanden vom Typ String sind, ist das Ergebnis die Verkettung der beiden Strings. Ansonsten wird die Operation wie bei allen anderen Operatoren als Double-Operation durchgeführt.
Boolean	Bei den Operatoren and, or und xor werden die Operanden in Boolean konvertiert, und der Ergebnistyp ist Boolean. Bei allen anderen Operatoren wird die Operation als Double -Operation durchgeführt.
Date	Bei den Operatoren + und – werden die Operanden in Date konvertiert, und der Ergebnistyp ist Date; werden zwei Date-Werte voneinander subtrahiert, ist er Double. Bei allen anderen Operatoren wird die Operation als Double-Operation durchgeführt.

Bei relationalen Operatoren werden beide Varianten in den gemeinsamen Typ umgewandelt, und die Ergebniswerte werden verglichen, so daß ein Boolesches Ergebnis erzielt wird. Der Wert Unassigned ist kleiner als alle andere Werte. Der Null-Wert ist größer als Unassigned und kleiner als alle anderen Werte.

Beim monadischen Minus-Operator (–) werden Strings vor der Operation in Double konvertiert und Boolesche Werte in den Typ Integer.

Für den Operator not gilt: Wenn der Typencode der Variante varBoolean ist, wird eine logische Negierungsoperation durchgeführt. Bei allen anderen Typencodes wird die Variante in Integer konvertiert, und es wird eine bitweise Negierungsoperation durchgeführt.


Siehe auch

Variantentypkonvertierungen

Werte in Varianten


Varianten-Arrays

Siehe auch	Beispiel	Variant-Typen

Varianten können Arrays aufnehmen, deren Größe und Dimensionen wechseln und die Elemente eines der Variantenbasistypen enthalten können. Die Elemente eines Varianten-Arrays weisen alle denselben Typ auf, aber wenn der Elementtyp Variant ist, können einzelne Elemente natürlich unterschiedliche Arten von Daten enthalten (auch andere Varianten-Arrays).

Varianten-Arrays werden in aller Regel mit der Standard-Prozedur VarArrayCreate erstellt.

In der folgenden Tabelle werden die Standard-Prozeduren und -Funktionen von Varianten-Arrays beschrieben, die alle in der Systemeinheit definiert sind.

Standard-Prozeduren und -Funktionen von Varianten-Arrays

Bezeichnung	Beschreibung
VarArrayCreate	Erstellt ein Varianten-Array mit der angegebenen Unter- und Obergrenze für jede Dimension und mit dem angegebenen Elementtyp. Als Elementtyp kommt jeder der varXXXX-Typencodes mit Ausnahme von varString in Frage. Zur Erstellung eines Varianten-Arrays mit Strings müssen Sie den Typencode varOleStr verwenden. Die Elemente des gerade erstellten Arrays werden alle auf Null gesetzt oder sind leer.
VarArrayOf	Erstellt ein eindimensionales Varianten-Array mit der angegebenen Liste von Elementen. Der Elementtyp des zurückgegebenen Varianten-Arrays ist Variant. Die Funktion VarArrayOf ist für eine nachträgliche "Stegreif"-Konstruktion von Varianten-Array-Parametern von Nutzen.
VarArrayRedim	Verändert die Größe eines Varianten-Arrays, indem die Obergrenze der niedrigstwertigen Dimension auf den angegebenen Wert gesetzt wird. Bestehende Elemente im Array werden beibehalten, und neue Elemente werden auf Null gesetzt oder sind leer.
VarArrayDimCount	Gibt die Anzahl der Dimensionen in einem Varianten-Array zurück; wenn das Argument kein Varianten-Array ist, wird die Zahl Null zurückgegeben.
VarArrayLowBound	Gibt die Untergrenze der angegebenen Dimension in einem Varianten-Array zurück.
VarArrayHighBound	Gibt die Obergrenze der angegebenen Dimension in einem Varianten-Array zurück.
VarArrayLock	Sperrt ein Varianten-Array und gibt einen Zeiger auf die Daten im Varianten-Array zurück. Mit dieser Funktion können Sie direkten Zugriff auf die Daten in einem Varianten-Array erhalten und dadurch die Leistungsfähigkeit beträchtlich steigern.
VarArrayUnlock	Hebt die Sperrung eines Varianten-Arrays wieder auf, die zuvor mit VarArrayLock vorgenommen wurde.
VarIsArray	Prüft, ob das Argument ein Varianten-Array enthält.
Hinweis	Der Elementtyp eines Varianten-Arrays kann nicht varString sein. Um Varianten-Arrays mit Strings zu erstellen, müssen Sie den Typencode varOleStr verwenden.

Wenn eine Variante ein Array enthält, kann auf die Elemente dieses Arrays zugegriffen werden, indem der Variante ein oder mehrere durch Kommata voneinander abgegrenzte Indexausdrücke in eckigen Klammern nachgestellt werden. Indexausdrücke sind immer vom Typ Integer. Beim Indizieren einer Variante wird eine EVariantError-Ausnahme ausgelöst, wenn die Variante kein Varianten-Array enthält, wenn eine falsche Anzahl von Indexausdrücken festgelegt wird oder wenn einer oder mehrere der Indexausdrücke außerhalb der Grenzen der zugehörigen Dimension liegen.

Der Zugriff auf Elemente in einem Varianten-Array erfolgt mit Ausdrücken; neue Werte werden ihnen mit Zuweisungsanweisungen zugewiesen. Beachten Sie dabei allerdings, daß es nicht möglich ist, ein Varianten-Array-Element als Parameter var zu übergeben.

Wenn eine Variante mit einem Varianten-Array zu einer anderen Variante zugewiesen oder als Werteparameter übergeben wird, wird eine Kopie des gesamten Arrays angefertigt, wahrscheinlich mit einem immensen Verbrauch an Speicherplatz. Aus diesem Grunde sollten Sie die Zuweisung von Varianten-Arrays zu anderen Varianten vermeiden, wo immer dies möglich ist; sofern keine gewichtigen Gründe dagegen sprechen, sollten Sie Varianten-Arrays als Parameter var oder const übergeben.


Beispiel für ein Varianten-Array

Varianten-Arrays werden in aller Regel mit der Standard-Prozedur VarArrayCreate erstellt, beispielsweise:

var

  A, B: Variant;

  I: Integer;

begin

  A := VarArrayCreate([0, 9], varInteger);

  for I := 0 to 9 do A[I] := I * I;

  B := VarArrayCreate([1, 3, 0, 9], varVariant);

  for I := 0 to 9 do B[1, I] := I;

  for I := 0 to 9 do B[2, I] := Sqrt(I);

  for I := 0 to 9 do B[3, I] := Format('Value=%d', [I]);

  ...

end;


Siehe auch

Varianten-Array-Dimensionen

Sperren von Varianten-Arrays


Varianten-Array-Dimensionen

Siehe auch	Beispiel	Varianten-Arrays

Die Größe eines Varianten-Arrays kann mit Hilfe der Standard-Prozedur VarArrayRedim verändert werden. Mit VarArrayRedim können Sie die Obergrenze der niedrigstwertigen (letzten) Dimension eines Varianten-Arrays ändern. Die Grenzen der anderen Dimensionen können nicht verändert werden. Bestehende Elemente eines Arrays bleiben über eine Operation zur Größenveränderung erhalten.

Mit den Standard-Funktionen VarArrayDimCount, VarArrayLowBound und VarArrayHighBound können Sie die Anzahl der Dimensionen in einem Varianten-Array und die Grenzen der einzelnen Dimensionen untersuchen. Dies kann sich als nützlich erweisen, wenn Sie allgemeine Routinen zur Manipulation von Varianten-Arrays schreiben, beispielsweise die im Beispiel-Bildschirm gezeigte Funktion VarArraySum.


Beispiele für Varianten-Array-Dimensionen

Im folgenden Ausschnitt aus einem Programmcode wird die Verwendung von VarArrayRedim demonstriert.

var

  A: Variant;

  I: Integer;

begin

  A := VarArrayCreate([0, 4], varOleStr);

  for I := 0 to 4 do A[I] := 'Ursprünglich';

  ...

  VarArrayRedim(A, 9);

  for I := 5 to 9 do A[I] := 'Zusätzlich';

  ...

end;

function VarArraySum(const A: Variant): Double;

var

  I: Integer;

begin

  if VarArrayDimCount(A) <> 1 then

    raise Exception.Create('Eindimensionales Varianten-Array erwartet');

  Result := 0;

  for I := VarArrayLowBound(A, 1) to VarArrayHighBound(A, 1) do

    Result := Result + Double(A[I]);

end;


Siehe auch

Sperren von Varianten-Arrays


Sperren von Varianten-Arrays

Siehe auch	Beispiel	Varianten-Arrays

Mit der Standard-Funktion VarArrayLock und der Standard-Prozedur VarArrayUnlock erhalten Sie direkten Zugriff auf die Daten in einem Varianten-Array.

Varianten-Arrays mit dem Elementtyp varByte (wie das von der vorstehenden Funktion erstellte Varianten-Array) stellen die empfohlene Methode zur Übergabe von binären Daten zwischen OLE-Automatisierungs-Controllern und Servern dar. Die Daten in diesen Arrays unterliegen keiner Translation, und der Zugriff auf die Daten kann auf effektive Weise mit den Routinen VarArrayLock und VarArrayUnlock erfolgen.


Beispiel für das Sperren von Varianten-Arrays

Mit der nachstehenden Funktion VarArrayLoadFile wird der Inhalt einer Datei in ein Varianten-Array mit Bytes geladen. Die Funktion verwendet VarArrayLock und VarArrayUnlock, um die Datei unmittelbar in das Array lesen zu können.

function VarArrayLoadFile(const FileName: string): Variant;

var

  F: file;

  Size: Integer;

  Data: PChar;

begin

  AssignFile(F, FileName);

  Reset(F, 1);

  try

    Size := FileSize(F);

    Result := VarArrayCreate([0, Size - 1], varByte);

    Data := VarArrayLock(Result);

    try

      BlockRead(F, Data^, Size);

    finally

      VarArrayUnlock(Result);

    end;

  finally

    CloseFile(F);

  end;

end;


Siehe auch

Varianten-Array-Dimensionen


Varianten und OLE-Automatisierungsobjekte

Siehe auch	Beispiel	Variant-Typen

Wenn eine Variante einen Bezug auf ein OLE-Automatisierungsobjekt enthält, ermöglicht Object Pascal es Ihnen, die Methoden des Objektes aufzurufen sowie seine Eigenschaften abzurufen und zu setzen. Dieser Funktionsumfang wird durch Verwendung der Unit OleAuto erreicht, und zwar indem ein Bezug auf OleAuto in der uses-Anweisung in eine Ihrer Units oder in die uses-Anweisung Ihres Programmes in der Bibliothek eingebaut wird.

Die Syntax für den Aufruf einer Methode oder für den Zugriff auf eine Eigenschaft eines OLE-Automatisierungsobjekts entspricht dem Aufruf einer normalen Methode bzw. dem Zugriff auf eine normale Eigenschaft.

Der Aufruf einer Methode eines OLE-Automatisierungsobjekts wird spät eingebunden; darüber hinaus ist die vorherige Deklarierung der Methode und ihrer Parameter nicht erforderlich. Im Gegensatz zum Aufruf einer normalen Methode läßt der Compiler bei einer OLE-Automatisierungsmethode die Festlegung jedes beliebigen Methodenbezeichner sowie einer beliebige Anzahl von Parametern jedes beliebigen Typs zu. Ob der Aufruf der Methode tatsächlich erfolgreich ist oder nicht, bleibt bis zur Ausführung des Aufrufs während der Programmausführung im ungewissen.

Bezeichner für Methoden, Eigenschaften und benannte Parameter von OLE-Automatisierungsobjekten dürfen Buchstaben aus einem internationalen Zeichensatz enthalten, beispielsweise á, ü und Ø.


Beispiel einer Variante mit OLE-Automatisierung

Im nachstehenden ist ein Ausschnitt aus einem Programmcode aufgeführt, in dem Aufrufe von OLE-Automatisierungsmethoden ausgeführt werden. Beachten Sie die Verwendung der Funktion CreateOleObject (in der OleAuto-Unit definiert) zur Erstellung einer Variante, die einen Bezug auf ein OLE-Automatisierungsobjekt enthält.

var

  Word: Variant;

begin

  Word := CreateOleObject('Word.Basic');

  Word.FileNew('Normal');

  Word.Insert('Dies ist die erste Zeile'#13);

  Word.Insert('Dies ist die zweite Zeile'#13);

  Word.FileSaveAs('c:\temp\test.txt', 3);

end;


Siehe auch

Variantenparameter bei der OLE-Automatisierung

Eigenschaften bei der OLE-Automatisierung


Variantenparameter bei der OLE-Automatisierung

Siehe auch	Beispiel	Varianten und OLE-Automatisierung

Beim Aufruf einer Methode eines OLE-Automatisierungsobjekts werden zwei Arten von Parametern unterstützt:

Positionsparameter

benannte Parameter.

Ein Positionsparameter ist einfach ein Ausdruck. Ein benannter Parameter besteht aus einem Parameterbezeichner, nach dem das Symbol Doppelpunkt-Gleich steht (:=),dem wiederum ein Ausdruck folgt.

Positionsparameter müssen im Aufruf einer Methode eines OLE-Automatisierungsobjekts vor den benannten Parametern stehen. Positionsparameter können ausgelassen werden, indem die führenden Parameterstellen freigelassen und weniger Parameterausdrücke als vom Aufruf der Methode erwartet geschrieben werden.

Hinweis:	OLE-Automatisierungs-Server unterstützen die benannten Parameter häufig nicht. Außerdem lassen einige OLE-Automatisierungs-Server nicht zu, daß Positionsparameter ausgelassen werden.

Die Parameter beim Aufruf einer OLE-Automatisierungsmethode können die folgenden Typen aufweisen: Integer, Real, String, Boolean und Variant. Ein Parameter wird als Bezug übergeben, wenn der Parameterausdruck nur aus einem Variablenbezug besteht und dieser Variablenbezug vom Typ Byte, Smallint, Integer, Single, Double, Currency, TDateTime, AnsiString (oder string), WordBool oder Variant ist. Wenn ein Parameterausdruck nicht nur aus einem Variablenbezug besteht oder der Ausdruck nicht einen der oben aufgeführten Typen aufweist, wird der Parameter als Wert übergeben. Wird ein Parameter als Bezug übergeben, kann die zugehörige Variable mit der aufgerufenen Methode bearbeitet werden.

Hinweis:	Die Übergabe eines Parameters als Bezug auf eine Methode, die einen Werteparameter erwartet, führt einfach dazu, daß OLE den Wert aus einem Bezugparameter entnimmt. Der umgekehrte Fall verursacht allerdings einen Fehler. In anderen Worten: Es ist ein Fehler, einen Werteparameter zu übergeben, wenn ein Bezugparameter erwartet wird.


Beispiele für Parameter bei OLE-Automatisierungsmethoden

Im folgenden werden einige Beispiele für Positionsparameter und benannte Parameter aufgeführt.

Word.FileSaveAs('test.doc');

Word.FileSaveAs('test.doc', 6);

Word.FileSaveAs('test.doc',,,'geheim');

Word.FileSaveAs('test.doc', Password := 'geheim');

Word.FileSaveAs(Password := 'geheim', Name := 'test.doc');

Beim ersten Aufruf wird ein Positionsparameter angegeben. Beim zweiten Aufruf werden zwei Positionsparameter angegeben. Beim dritten Aufruf werden vier Positionsparameter angegeben, von denen die beiden mittleren ausgelassen wurden. Beim vierten Aufruf wird ein Positionsparameter und ein benannter Parameter angegeben. Beim fünften Aufruf schließlich werden keine Positionsparameter und zwei benannte Parameter angegeben. Beachten Sie, daß bei der Verwendung von benannten Parametern die Reihenfolge der Parameter keine Rolle spielt.


Siehe auch

Eigenschaften bei der OLE-Automatisierung


Eigenschaften bei der OLE-Automatisierung

Siehe auch	Varianten und OLE-Automatisierung

Der Zugriff auf die Eigenschaften eines OLE-Automatisierungsobjekts erfolgt nach denselben Regeln wie der Aufruf von Methoden. Wenn der Zugriff auf eine Eigenschaft in einem Ausdruck verwendet wird, wird der Wert der Eigenschaft gelesen, und wenn der Zugriff auf eine Eigenschaft auf der linken Seite einer Zuweisungsanweisung verwendet wird, wird der Wert der Eigenschaft geschrieben. Bei Array-Eigenschaften muß die Liste der Indexparameter in eckige Klammern gesetzt werden.

Der Object Pascal-Compiler läßt in einem Aufruf einer OLE-Automatisierungsmethode und beim Zugriff auf eine OLE-Automatisierungseigenschaft die Festlegung jedes beliebigen Methoden- und Eigenschaftenbezeichners sowie jeder beliebigen Anzahl von Parametern jedes beliebigen Typs zu. Die Aufrufinformationen werden vom Compiler gepackt, und bis zur Ausführung des Aufrufs oder des Zugriffs auf die Eigenschaft während der Programmausführung bleibt der Erfolg der Angelegenheit ungewiß.

 Wenn der Aufruf einer OLE-Automatisierungsmethode oder der Zugriff auf eine OLE-Automatisierungseigenschaft fehlschlägt, wird eine EOleError-Ausnahme ausgelöst. Der Aufruf oder der Zugriff auf eine Eigenschaft kann aus den folgenden Gründen fehlschlagen:

Der im Variantenmethoden- oder Varianteneigenschaftendesignator festgelegte Variantenausdruck bezieht sich zur Zeit nicht auf ein OLE-Automatisierungsobjekt.

Der Methoden- oder Eigenschaftenbezeichner wird vom OLE-Automatisierungsobjekt nicht unterstützt.

Es wurde eine falsche Anzahl von Parametern festgelegt, oder der Typ eines oder mehrerer Parameter war nicht korrekt.

Ein oder mehrere Positionsparameter wurden ausgelassen.

Es wurden benannte Parameter angegeben, die aber nicht vom OLE-Automatisierungsobjekt unterstützt werden.

In einem Ausdruck wurde ein Aufruf einer Methode verwendet, aber die Methode gab keinen Wert zurück.

Die Methode oder der Zugriff auf eine Eigenschaft wurde ordnungsgemäß aufgerufen, es wurde jedoch eine Ausnahme zurückgegeben.

Wenn der Aufruf einer OLE-Automatisierungsmethode oder der Zugriff auf eine OLE-Automatisierungseigenschaft fehlschlägt, enthält das EOleError-Ausnahmeobjekt eine Fehlermeldung, die den Grund für den Fehlschlag erläutert.


Siehe auch

Variantenparameter bei der OLE-Automatisierung


Compiler-Meldungen

Fehlermeldungen während der Laufzeit

In der folgenden Liste sind alle Fehler-, Warn- und Hinweismeldungen, die der Object Pascal-Compiler erzeugen kann, in alphabetischer Reihenfolge aufgeführt. Weitere Informationen zu einer bestimmten Meldung erhalten Sie durch Klicken auf den entsprechenden Text in der Liste.

Da viele der Meldungen variablen Text enthalten, könnte das Auffinden einer bestimmten Meldung in der Liste nicht ganz problemlos sein.

Hinweis	Informationen zu einer in der Integrated Development Environment (IDE) erhaltenen Meldung können am bequemsten abgerufen werden, indem Sie die Meldung im Meldungsfenster markieren und die Taste F1 betätigen.

';' not allowed before 'ELSE'

'<clause>' clause not allowed in OLE automation section

<clause1> clause expected, but <clause2> found

<Filename>: <RLink32 error message>

'<name>' is not a type identifier

'<name>' not previously declared as a PROPERTY

<RLink32 error message>

<token1> expected but <token2> found

16-Bit fixup encountered in object file '<Filename>'

486/487 instructions not enabled

Abstract methods must be virtual or dynamic

Array type required

Assignment to FOR-Loop variable '<name>'

Bad argument type in variable type array constructor

Bad file format '<name>'

Bad file format: <Filename>

Bad global symbol definition: '<name>' in object file '<Filename>'

Bad specification of M format

Bad unit format: <Filename>

BREAK or CONTINUE outside of loop

Cannot add or subtract relocatable symbols

Cannot assign to a read-only property

Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause

Cannot initialize local variables

Cannot initialize multiple variables

Cannot initialize thread local variables

Cannot override a static method

Cannot read a write-only property

Case label outside of range of case expression

Circular unit reference to <Unitname>

Class already has a default property

Class does not have a default property

Class or object types only allowed in type section

Class type required

Close error on <Filename>

Compile terminated by user

Constant expected

Constant expression expected

Constant expression violates subrange bounds

Constant object cannot be passed as var parameter

Constant or type identifier expected

Constants cannot be used as open array arguments

Constructing instance of '<name>' containing abstract methods

Constructors and destructors not allowed in OLE automation section

Could not compile used unit '<Unitname>'

Could not create output file <Filename>

Could not load RLINK32.DLL

Data type too large: exceeds 2 GB

Declaration of <name> differs from previous declaration

Default property must be an array property

Default values must be of ordinal, pointer or small set type

Destination cannot be assigned to

Destination is inaccessible

Dispid '<number>' already used by '<name>'

Dispid clause only allowed in OLE automation section

Division by zero

Division by zero

Duplicate case label

Duplicate message method index

Duplicate tag value

Dynamic method or message handler not allowed here

Dynamic methods and message handlers not allowed in OLE automation section

Element 0 inaccessible - use 'Length' or 'SetLength'

Error in numeric constant

EXCEPT or FINALLY expected

EXPORTS allowed only at global scope

Expression has no value

Expression is not a procedure

Expression too complicated

Field definition not allowed in OLE automation section

Field definition not allowed after methods or properties

Field or method identifier expected

File not found: <Filename>

File type not allowed here

Fn requires 2 <= n <= 18

For loop control variable must be simple local variable

For loop control variable must have ordinal type

FOR or WHILE loop executes zero times - deleted

FOR-Loop variable '<name>' cannot be passed as var parameter

FOR-Loop variable '<name>' may be undefined after loop

Format specifier must be C, S, D, H, X, Fn, P, R or nM

Function needs result type

'GOTO <label>' leads into or out of TRY statement

Identifier redeclared: '<name>'

Illegal character in input file: '<Char>' (<Hexadecimal value>)

Illegal message method index

Illegal reference to symbol '<name>' in object file '<Filename>'

Illegal type in OLE automation section: '<typename>'

Illegal type in Read/Readln statement

Illegal type in Write/Writeln statement

Inaccessible value

Incompatible format specification

Incompatible types: '<name>' and '<name>'

Incompatible types: <text>

Incompatible types

Inline assembler stack overflow

Inline assembler syntax error

Instance variable '<name>' inaccessible here

Integer constant or variable name expected

Integer constant too large

Internal error: <ErrorCode>

Invalid combination of opcode and operands

Invalid compiler directive: <Directive>

Invalid function result type

Invalid message parameter list

Invalid register combination

Invalid typecast

Label '<name>' is not declared in current procedure

Label already defined: '<Labelname>'

Label declaration not allowed in interface part

Label declared and referenced, but not set: '<label>'

Label expected

Left side cannot be assigned to

Line too long (more than 255 characters)

Local class or object types not allowed

Local procedure/function '<name>' assigned to procedure variable

LOOP/JCXZ distance out of range

Low bound exceeds high bound

Memory reference expected

Method '<name>' hides virtual method of base type '<name>'

Method '<name>' not found in base class

Method identifier expected

Missing ENDIF directive

Missing operator or semicolon

Missing or invalid conditional symbol in '$<symbol>' directive

Missing parameter type

Necessary library helper function was eliminated by linker

No definition for abstract method '<name>' allowed

No source line for this procedure

Not enough actual parameters

Number of elements differs from declaration

Numeric overflow

Object or class type required

Object type required

Only register calling convention allowed in OLE automation section

Operand size mismatch

Operator not applicable to this operand type

Order of fields in record constant differs from declaration

Ordinal type required

Out of memory

Overflow in conversion or arithmetic operation

Overriding automated virtual method '<name>' cannot specify a dispid

PACKED not allowed here

Pointer type required

Procedure cannot have a result type

Procedure DISPOSE needs destructor

 Procedure FAIL only allowed in constructor

 Procedure NEW needs constructor

PROCEDURE or FUNCTION expected

Procedure or function name expected

Program or unit recursively uses itself

Property '<name>' does not exist in base class

Published property '<name>' cannot be of type <type>

Published Real property '<name>' must be Single, Double or Extended

Re-raising an exception only allowed in exception handler

Read error on <Filename>

Record, object or class type required

Redeclaration of '<name>' hides a member in the base class

Redeclaration of property not allowed in OLE automation section

Return value of function '<Functionname>' might be undefined

Seek error on <Filename>

Segment/Offset pairs not supported in Borland 32-bit Pascal

Sets may have at most 256 elements

Size of published set '<name>' is >4 bytes

Slice standard function only allowed as open array argument

Statement expected, but expression of type '<type>' found

Statements not allowed in interface part

String constant too long

String constant truncated to fit STRING[<number>]

Strings may have at most 255 elements

Structure field identifier expected

Syntax error in real number

System unit out of date or corrupted: missing '<name>'

Text after final 'END.' - ignored by compiler

This form of method call only allowed for class methods

This form of method call only allowed in methods of derived types

This type cannot be initialized

Thread local variables cannot be ABSOLUTE

Thread local variables cannot be local to a function

Too many actual parameters

Too many conditional symbols

Type '<name>' has no type info

Type '<name>' is not yet completely defined

Type '<name>' must be a class to have a PUBLISHED section

Type '<name>' must be a class to have OLE automation

Type '<name>' needs finalization - not allowed in file type

Type '<name>' needs finalization - not allowed in variant record

Type expected

Type not allowed in OLE Automation call

Type of expression must be BOOLEAN

Type of expression must be INTEGER

TYPEINFO standard function expects a type identifier

TYPEOF can only be applied to object types with a VMT

Types of actual and formal var parameters must be identical

Undeclared identifier: '<name>'

Unexpected end of file in comment started on line <Number>

Unit <Unit1> was compiled with a different version of <Unit2>

Unit name mismatch: '<Unitname>'

Unknown directive: '<Directive>'

Unnamed arguments must precede named arguments in OLE Automation call

Unsatisfied forward or external declaration: '<Procedurename>'

Unterminated string

Value assigned to '<name>' never used

Variable '<name>' inaccessible here due to optimization

Variable '<name>' is declared but never used in '<name>'

Variable '<name>' might not have been initialized

Variable required

Virtual constructors are not allowed

Write error on <Filename>

Wrong or corrupted version of RLINK32.DLL


Fehlermeldung "Ordinal type required "
"Ordinal type required"

Siehe auch	Beispiel	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat an dieser Stelle einen Ordinaltyp erwartet.

Ordinaltypen sind die vordefinierten Typen Integer, Char, WideChar und Boolean sowie deklarierte Aufzählungstypen. Ordinaltypen werden in mehreren verschiedenen Situationen erwartet:

Der Indextyp eines Arrays muß Ordinal sein.

Die Ober- und Untergrenze eines Untermengen-Typs müssen konstante Ausdrücke vom Typ Ordinal sein.

Der Elementtyp einer Menge muß Ordinal sein.

Der Auswahl-Ausdruck einer Case-Anweisung muß vom Typ Ordinal sein.

Das erste Argument der Standard-Prozeduren Inc und Dec muß eine Variable vom Typ Ordinal oder Zeiger sein.


Beispiele

{ Der Indextyp eines Arrays muß Ordinal sein - der Typ TByteSet ist eine Menge, kein Ordinal. }

program Produce;

type

  TByteSet = set of 0..7;

var

  BitCount: array[TByteSet] of Integer;

begin

end.

{ Geben Sie einen Ordinaltyp als Indextyp des Arrays an. }

program Solve;

type

  TByteSet = set of 0..7;

var

  BitCount: array[Byte] of Integer;

begin

end.


Siehe auch

Array-Typen

Untermengen-Typen

Aufzählungstypen

Case-Anweisung

Prozedur Inc

Prozedur Dec


Fehlermeldung "File type not allowed here "
"File type not allowed here"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dateitypen sind als Wertparameter und als Basistyp eines Dateityps selber nicht zulässig. Außerdem dürfen sie nicht als Rückgabewerte von Funktionen eingesetzt werden, und sie können nicht zugewiesen werden - diese Fehler führen allerdings zu anderen Fehlermeldungen.


Beispiele

{ In diesem Beispiel liegt das Problem darin, daß T ein Wertparameter vom Typ Text ist, welcher wiederum ein Dateityp ist. Denken Sie daran: Ganz gleich, was zu einem Wertparameter geschrieben wird - auf die Kopie der Variable beim Aufrufenden wird kein Einfluß genommen. Die Deklarierung einer Datei als Wertparameter hat daher wenig Sinn. }

program Produce;

procedure WriteInteger(T: Text; I: Integer);

begin

  Writeln(T, I);

end;

begin

end.

{ Deklarierung des Parameters als Parameter var beseitigt das Problem. }

program Solve;

procedure WriteInteger(var T: Text; I: Integer);

begin

  Writeln(T, I);

end;

begin

end.


Siehe auch

Dateitypen


Fehlermeldung "Low bound exceeds high bound "
"Low bound exceeds high bound"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn die Untergrenze eines Untermengen-Typs über dessen Obergrenze liegt oder wenn die Untergrenze einer Case-Label-Menge über dessen Obergrenze liegt.


Beispiele

{ In diesem Beispiel löst der Compiler eine Fehlermeldung aus, anstatt die Bereiche als leer zu behandeln. Aller Wahrscheinlichkeit nach war das Vertauschen der Grenzen nicht beabsichtigt. }

program Produce;

type

  SubrangeType = 1..0;              { Daraus folgt: Untergrenze liegt über Obergrenze  }

begin

  case True of

  True..False:                      { Daraus folgt: Untergrenze liegt über Obergrenze  }

    Writeln('Erwartetes Ergebnis');

  else

    Writeln('Nicht erwartetes Ergebnis');

  end;

end.

{ Stellen Sie sicher, daß Sie die Grenzen in der richtigen Reihenfolge festgelegt haben. }

program Solve;

type

  SubrangeType = 0..1;

begin

  case True of

  False..True:

    Writeln('Erwartetes Ergebnis');

  else

    Writeln('Nicht erwartetes Ergebnis');

  end;

end.


Fehlermeldung "Program or unit recursively uses itself "
"Program or unit recursively uses itself"

Beispiel	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn eine uses-Anweisung dieselbe Unit oder dasselbe Programm noch einmal lädt. Dieser Fall kann eintreten, wenn Sie die Compiler-Anweisung -P aufgrund der Kürzung von Dateinamen festlegen (suchen Sie nach Dateinamen mit dem Schema 8.3), wenn die ersten acht Zeichen dieser Namen identisch sind.


Beispiele

{ Die folgende Unit in der Datei Produce_.pas führt zu einer Fehlermeldung, wenn sie mit der Option use-short-file-names compiliert wird }

unit Produce_Unit_1;

interface

uses Produce_Unit_2;

implementation

end.


Fehlermeldung "Prozedur einen zu geringen lokalen Adressenplatz"
"Prozedur einen zu geringen lokalen Adressenplatz"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird bei der Intel-Architektur nicht benutzt.


Fehlermeldung "Label '<name>' is not declared in current procedure "
"Label '<name>' is not declared in current procedure"

Beispiele	Compiler-Fehlermeldungen

Im Gegensatz zu Standard Pascal ist es bei Borland Pascal nicht zulässig, daß mit einem goto aus der aktuellen Prozedur herausgesprungen wird. Diese Idee ist allerdings vor allem bei der Fehlerbehandlung von Nutzen, und Borland Pascal bietet einen allgemeineren und mehr strukturierten Mechanismus zur Fehlerbehandlung: die Ausnahmenbehandlung.


Beispiele

{ Im nachstehenden Beispiel wird versucht, die Programmausführung mit einem nichtlokalen goto anzuhalten. }

program Produce;

label 99;

procedure MyProc;

begin

  { Etwas geht hier völlig schief... }

  goto 99;

end;

begin

  MyProc;

  99:

    Writeln('Schwerer Fehler');

end.

{ In unserem Lösungsvorschlag haben wir die Ausnahmenbehandlung benutzt, um das Programm zu stoppen. Dies hat außerdem den Vorteil, daß eine Fehlermeldung angezeigt werden kann. Eine andere Lösung wäre die Verwendung der Standardprozeduren Halt oder RunError. }

program Solve;

uses SysUtils;

procedure MyProc;

begin

  { Etwas geht hier völlig schief... }

  raise Exception.Create('Schwerer Fehler');

end;

begin

  try

    MyProc;

  except

    on E: Exception do Writeln(E.Message);

  end;

end.


Fehlermeldung "Local procedure/function '<name>' assigned to procedure variable "
" Local procedure/function '<name>' assigned to procedure variable"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, eine lokale Prozedur zu einer Prozedurenvariablen zuzuweisen oder als Prozedurenparameter zu übergeben. Dies ist nicht zulässig, da die lokale Prozedur selbst dann aufgerufen werden kann, wenn die sie umschließende Prozedur nicht aktiv ist. Diese Situation würde zu einem Absturz des Programms führen, wenn die lokale Prozedur versucht, Variablen der sie umschließenden Prozedur aufzurufen.


Beispiele

{ In diesem Beispiel wird versucht, eine lokale Prozedur einer Prozedurenvariable zuzuweisen. Dies ist unzulässig, da es zu Instabilität während der Programmausführung kommen kann. }

program Produce;

var

  P: Procedure;

procedure Outer;

  procedure Local;

  begin

    Writeln('Local wird ausgeführt');

  end;

begin

  P := Local;       { <-- Hier die Fehlermeldung }

end;

begin

  Outer;

  P;

end.

{ Die Lösung liegt darin, die lokale Prozedur aus der sie umschließenden Prozedur herauszubringen. }

program Solve;

var

  P: Procedure;

procedure NonLocal;

begin

  Writeln('NonLocal wird ausgeführt');

end;

procedure Outer;

begin

  P := NonLocal;

end;

begin

  Outer;

  P;

end.


Fehlermeldung "Missing ENDIF directive "
"Missing ENDIF directive"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn der Compiler nach einer Anweisung $IFDEF, $IFNDEF oder $IFOPT keine zugehörige Anweisung $ENDIF findet.


Beispiele

(* In diesem Beispiel haben wird das Zeichen $ in der Anweisung {$Endif} ausgelassen, so daß der Compiler diese Anweisung fälschlicherweise als Kommentar ansah. *)

program Produce;

{$AppType Console}

begin

{$IfOpt O+}

  Writeln('Mit Optimierungen compiliert');

{$Else}

  Writeln('Ohne Optimierungen compiliert');

{Endif}

end.	{ <-- Hier die Fehlermeldung }

{ Die Lösung liegt einfach darin, darauf zu achten, daß bei allen bedingten Anweisungen eine gültige Anweisung $ENDIF vorhanden ist. }

program Solve;

{$AppType Console}

begin

{$IfOpt O+}

  Writeln('Mit Optimierungen compiliert');

{$Else}

  Writeln('Ohne Optimierungen compiliert');

{$Endif}

end.


Siehe auch

Bedingte Anweisungen


Fehlermeldung "Method identifier expected "
"Method identifier expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird in mehreren verschiedenen Situationen angezeigt:

Eigenschaften in einem Abschnitt Automated müssen für den Zugriff Methoden verwenden; sie können in ihren Lese- oder Schreibanweisungen keine Felder verwenden.

Sie haben versucht, eine Klassen-Methode gemäß der Syntax „ClassType.MethodName“ aufzurufen, aber „MethodName“ entsprach nicht der Bezeichnung einer Methode.

Sie haben versucht, eine vererbte Methode gemäß der Syntax „Inherited MethodName“ aufzurufen, aber  „MethodName“ entsprach nicht der Bezeichnung einer Methode.


Beispiele

{ In diesem Beispiel wurde versucht, eine automatisierte Eigenschaft zu deklarieren, die auf ein Feld direkt zugreift. Der zweite Fehler wurde durch den Versuch hervorgerufen, zu einem Feld in der Basisklasse zu gelangen - dies ist ebenfalls nicht zulässig. }

program Produce;

type

  TMyBase = class

    Field: Integer;

  end;

  TMyDerived = class(TMyBase)

    Field: Integer;

    function Get: Integer;

  automated

    property Prop: Integer read Field;    { <-- Hier die Fehlermeldung }

  end;

function TMyDerived.Get: Integer;

begin

  Result := TMyBase.Field;                { <-- Hier die Fehlermeldung }

end;

begin

end.

{ Das erste Problem wird durch Zugriff auf ein Feld mit Hilfe einer Methode behoben. Das zweite Problem kann behoben werden, indem der Zeiger Self auf den Basisklassentyp umgewandelt wird und der Zugriff auf das Feld ohne dessen Hilfe erfolgt. }

program Solve;

type

  TMyBase = class

    Field: Integer;

  end;

  TMyDerived = class(TMyBase)

    Field: Integer;

    function Get: Integer;

  automated

    property Prop: Integer read Get;

  end;

function TMyDerived.Get: Integer;

begin

  Result := TMyBase(Self).Field;

end;

begin

  Writeln( TMyDerived.Create.Prop );

end.


Fehlermeldung "Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden"
"Constant object cannot be passed as var parameter"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Da Variablenparameter nur durch die aufgerufene Prozedur oder Funktion geändert werden sollten, können Sie ein Konstantenobjekt nicht an einen Variablenparameter übergeben. Falls Sie lediglich eine umfangreiche Datenstruktur effizient übergeben möchten und die aufgerufene Funktion die Struktur nicht verändern soll, können Sie statt dessen den Parameter const verwenden.


Beispiele

{ In diesem Beispiel besitzt function einen Variablenparameter, aber wir übergeben eine Konstante. }

program Produce;

{$AppType Console}

function Max(var A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := Low(Integer);

  for I := 0 to High(A) do

    if Result < A[I] then

       Result := A[I];

end;

begin

  Writeln( Max([1,2,3]) );   { <-- Hier die Fehlermeldung }

end.

{ Die Lösung liegt darin, den Parameter als Konstantenparameter zu deklarieren (wir wollen ihn schließlich nicht verändern). Eine andere Möglichkeit besteht darin, den Aufruf so zu verändern, daß keine Konstanten übergeben werden. }

program Solve;

{$AppType Console}

function Max(const A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := Low(Integer);

  for I := 0 to High(A) do

    if Result < A[I] then

      Result := A[I];

end;

begin

  Writeln( Max([1,2,3]) );

end.


Fehlermeldung "FOR-Loop variable '<name>' cannot be passed as var parameter n werden"
"FOR-Loop variable '<name>' cannot be passed as var parameter n werden"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird angezeigt, wenn Sie die Steuervariable einer for-Schleife als Variablenparameter übergeben. Die aufgerufene Prozedur oder Funktion könnte diese Steuervariable verändern, so daß die for-Schleife nicht mehr ordnungsgemäß abgearbeitet werden kann. Überprüfen Sie, ob der Parameter besser als Wertparameter oder als Konstantenparameter deklariert werden sollte. Falls dies möglich ist, wird die Effizienz der aufgerufenen Prozedur und auch der for-Schleife erheblich gesteigert werden.


Beispiele

{ In diesem Beispiel wird die Steuervariable I als Variablenparameter an die Prozedur MyProc übergeben, wodurch eine Warnmeldung ausgegeben wird. }

program Produce;

{$WARNINGS ON}

procedure MyProc(var I: Integer);

begin

  Writeln(I);

end;

var

  I: Integer;

begin

  for I := 1 to 10 do

    MyProc(I);            { <-- Hier die Warnmeldung }

end.

{ Die Lösung in diesem Fall war die Abänderung der Parameterdeklarierung in einen Konstantenparameter. Eine andere Möglichkeit besteht darin, die Steuervariable einer anderen, zusätzlichen Variablen zuzuweisen und diese zusätzliche Variable zu übergeben. }

program Solve;

{$WARNINGS ON}

procedure MyProc(const I: Integer);

begin

  Writeln(I);

end;

var

  I: Integer;

begin

  for I := 1 to 10 do

    MyProc(I);

end.


Fehlermeldung "BREAK or CONTINUE outside of loop "
"BREAK or CONTINUE outside of loop"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat eine Break- oder Continue-Anweisung gefunden, die sich nicht innerhalb einer while - oder repeat-Schleife befindet. Diese beiden Anweisungen dürfen nur in Schleifen verwendet werden.


Beispiele

{ Das nachstehende Beispiel zeigt, wie eine continue-Anweisung sich scheinbar in einer Schleife befindet, aber aufgrund der Struktur aus zusammengesetzten Anweisungen von Pascal sich tatsächlich nicht innerhalb einer Schleife befindet. }

program Produce;

  procedure Error;

  var

    I: Integer;

  begin

    I := 0;

    while I < 100 do

      Inc(I);

      if Odd(I) then

      begin

        Inc(I);

        Continue;

      end;

  end;

begin

end.

{ Häufig kostet es nur wenig Mühe, eine zusammengesetzte Anweisung außerhalb der Schleife zu erstellen, um so sicherzustellen, daß die CONTINUE- oder BREAK-Anweisungen innerhalb der Schleife stehen. }

program Solve;

  procedure Error;

  var

    I: Integer;

  begin

    I := 0;

    while I < 100 do

    begin

      Inc(I);

      if Odd(I) then

      begin

        Inc(I);

        Continue;

      end;

    end;

  end;

begin

end.


Fehlermeldung "Division by zero "
"Division by zero"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat in Ihrem Programm eine Konstantendivision durch Null entdeckt.

Überprüfen Sie die Konstantenausdrücke, und legen Sie sie erneut fest, so daß der Fehler einer Division durch Null nicht auftreten kann.


Fehlermeldung "Type of expression must be BOOLEAN "
"Type of expression must be BOOLEAN"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird ausgegeben, wenn ein Ausdruck als Bedingung benutzt wird und daher vom Typ Boolean sein muß. Dies trifft für den Steuerausdruck der Anweisungen if, while und repeat zu sowie für den Ausdruck, mit dem ein bedingter Programmstopp gesteuert wird.


Beispiele

{ Hier hat ein C++-Programmierer einfach eine Zeigervariable als Bedingung einer if-Anweisung benutzt. }

program Produce;

var

  P: Pointer;

begin

  if P then

    Writeln('P <> nil');

end.

{ Bei Pascal müssen Sie in diesem Fall etwas expliziter programmieren. }

program Solve;

var

  P: Pointer;

begin

  if P <> nil then

    Writeln('P <> nil');

end.


Fehlermeldung "Overflow in conversion or arithmetic operation "
"Overflow in conversion or arithmetic operation"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat einen Überlauf in einem arithmetischen Ausdruck gefunden: Das Ergebnis des Ausdrucks ist zu groß, um mit 32 Bit dargestellt werden zu können.

Überprüfen Sie die Berechnungen, um sicherzustellen, daß der Wert von der Hardware des Computers dargestellt werden kann.


Fehlermeldung "Data type too large: exceeds 2 GB "
"Data type too large: exceeds 2 GB"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Datentyp festgelegt, der zu groß ist, um vom Compiler dargestellt werden zu können. Sie müssen den Umfang der Beschreibung dieses Typs verringern.


Beispiele

{ Es ist offensichtlich, warum diese Deklarierungen zu Fehlermeldungen führen. }

program Produce;

type

  EnormousArray = array[0..MaxLongint] of Longint;

  BigRecord = record

    Points: array[1..10000] of Extended;

  end;

var

  Data: array[0..500000] of BigRecord;

begin

end.

{ Eine einfache Methode zur Vermeidung dieser Fehlermeldung liegt darin, darauf zu achten, daß der Umfang Ihrer Daten unterhalb von 2 GB bleibt. Eine etwas kompliziertere Methode wäre die Restrukturierung Ihrer Daten, die hier mit der Deklarierung BigRecord beginnt. }

program Solve;

type

  EnormousArray = array[0..MaxLongint div 8] of Longint;

  DataPoints = ^DataPointDesc;

  DataPointDesc = array[1..10000] of Extended;

  BigRecord = record

    Points: DataPoints;

  end;

var

  Data: array[0..500000] of BigRecord;

begin

end.


Fehlermeldung "Integer constant too large "
"Integer constant too large"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Integerkonstante festgelegt, für deren Darstellung mehr als 32 Bit benötigt werden.


Beispiele

{ Beide Konstanten im folgenden Beispiel sind zu groß, als daß sie mit 32 Bit dargestellt werden könnten; der Compiler wird daher eine Fehlermeldung ausgeben. }

program Produce;

const

  VeryDecimal = 123456789;

  VeryBigHex = $123456789;

begin

end.

{ Überprüfen Sie die von Ihnen festgelegten Konstanten, und achten Sie darauf, daß sie jeweils mit 32 Bit dargestellt werden können. }

program Solve;

const

  VeryDecimal = 12345678;

  VeryBigHex = $12345678;

begin

end.


Fehlermeldung "16-Bit fixup encountered in object file '<Filename>' "
"16-Bit fixup encountered in object file '<Filename>'"

Compiler-Fehlermeldungen

Beschreibung

Ein 16-Bit-Fixup wurde in einem der mit Hilfe der Compileranweisung $L mit Ihrem Programm verknüpften Objektmodule gefunden. Der Compiler unterstützt nur 32-Bit-Fixups in verknüpften Objektmodulen.

Achten Sie darauf, daß das verknüpfte Objektmodul ein 32-Bit-Objektmodul ist.


Fehlermeldung " syntax error "
" syntax error"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Ausdruck eingegeben, den der Inline Assembler nicht als gültige Assembleranweisung interpretieren kann.

Untersuchen Sie die betreffende Assembleranweisung, und achten Sie darauf, daß sie der ordnungsgemäßen Syntax entspricht.


Beispiele

program Produce;

  procedure Assembly;

  asm

    adx	eax, 151

  end;

begin

end.

program Solve;

  procedure Assembly;

  asm

    add	eax, 151

  end;

begin

end.


Fehlermeldung " stack overflow "
" stack overflow"

Compiler-Fehlermeldungen

Beschreibung

Der Programmcode Ihres Inline-Assemblers hat die Kapazität des Inline Assemblers überschritten.

Wenden Sie sich bitte an Borland International, wenn Sie diesem Fehler gegenüberstehen.


Fehlermeldung "Operand size mismatch "
"Operand size mismatch"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die vom Anweisungsoperanden benötigte Größe stimmt nicht mit der gegebenen Größe überein.


Beispiele

{ Im folgenden Beispiel wird der Compiler sich beschweren, weil der Operator 'offset' ein 'dword' erzeugt, der Operator aber ein 'byte' erwartet. }

program Produce;

var

  V: Integer;

  procedure Assembly;

  asm

    db offset V

  end;

begin

end.

{ Die Lösung für dieses Beispiel liegt darin, den Operator so zu ändern, daß er ein 'dword' empfangen kann. Im allgemeinen wird es notwendig sein, daß Sie eine genaue Untersuchung Ihres Programmcodes durchführen und dabei darauf achten, daß Operator und Operatorgröße übereinstimmen. }

program Solve;

var

  V: Integer;

  procedure Assembly;

  asm

    dd offset v

  end;

begin

end.


Siehe auch

Inline Assembler


Fehlermeldung "Memory reference expected "
"Memory reference expected"

Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat einen Speicherreferenzausdruck erwartet, konnte jedoch keinen solchen Ausdruck finden.

Achten Sie darauf, daß die betreffende Anweisung tatsächlich eine Speicherreferenz ist.


Fehlermeldung "Constant expected "
"Constant expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat eine Konstante erwartet, konnte jedoch keine finden.

Viele der Anweisungen des Inline Assemblers erfordern Konstanten für eine ordnungsgemäße Assemblierung. Verändern Sie die betreffende Anweisung, so daß während der Assemblierung eine Konstante zur Verfügung steht.


Beispiele

{ Der Inline Assembler kann keine MOD-Operation mit einer Pascal-Variablen durchführen; der nachstehende Programmcode wird daher eine Fehlermeldung auslösen. }

program Produce;

  procedure Assembly(X: Integer);

  asm

    mov	 ax, X MOD 10

  end;

begin

end.


Fehlermeldung "Type expected "
"Type expected"

Compiler-Fehlermeldungen

Beschreibung

Wenden Sie sich bitte an Borland International, wenn Sie diesem Fehler gegenüberstehen.


Fehlermeldung "Type of expression must be INTEGER "
"Type of expression must be INTEGER"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird nur angezeigt, wenn der Konstantenausdruck, der die Anzahl von Zeichen in einem kurzen String-Typ angibt, keine ganze Zahl ist.


Beispiele

{ Im nachstehenden Beispiel wird versucht, die Anzahl von Elementen in einem String als abhängig vom größten Element vom Typ Farbe festzulegen - leider ist der Elementzähler unzulässigerweise vom Typ Farbe. }

program Produce;

type

  Color = (red,green,blue);

var

  S3: string[Succ(High(Color))];

begin

end.

program Solve;

type

  Color = (red,green,blue);

var

  S3: string[Ord(High(Color))+1];

begin

end.


Fehlermeldung "Cannot add or subtract relocatable symbols "
"Cannot add or subtract relocatable symbols"

Beispiel	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler kann keine Speicheradresse hinzufügen oder entfernen, die möglicherweise vom Linker geändert wurde.

Achten Sie darauf, daß Sie keine relozierbaren Adressen aus Ihrem Inline Assembler-Anweisungen heraus hinzuzufügen oder zu entfernen versuchen.


Beispiel

{ Globale Variablen fallen in die Elementklasse, die relozierbare Adressen erzeugt, und der Inline Assembler kann diese Adressen daher nicht hinzufügen oder entfernen. }

program Produce;

var

  A: array[1..10] of Integer;

  EndOfA: Integer;

  procedure Relocatable;

  begin

  end;

  procedure Assembly;

  asm

    mov eax, A + EndOfA

  end;

begin

end.


Fehlermeldung "Invalid register combination "
"Invalid register combination"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine ungültige Kombination in einer Inline Assembler-Anweisung festgelegt. Weitere Informationen zu zulässigen Adressierungsmodi mit der 80x86-Prozessorfamilie von Intel finden Sie in einem Assemblersprachenhandbuch.


Beispiele

{ Der in dieser mov-Anweisung festgelegte rechte Operand ist nicht zulässig. }

program Produce;

  procedure AssemblerExample;

  asm

    mov eax, [ecx + esp * 4]

  end;

begin

end.

{ Der von dem rechten Operand in dieser mov-Anweisung festgelegte Adressierungsmodus ist zulässig. }

program Solve;

  procedure AssemblerExample;

  asm

    mov eax, [ecx + ebx * 4]

  end;

begin

end.


Fehlermeldung "Numeric overflow "
"Numeric overflow"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat einen numerischen Überlauf in einem der Ausdrücke entdeckt.


Beispiele

{ Dieser Fehler wird ausgelöst, wenn eine Zahl festgelegt wird, für deren Darstellung mehr als 32 Bit benötigt werden. }

program Produce;

  procedure AssemblerExample;

  asm

    mov eax, $0ffffffffffffffffffffff

  end;

begin

end.

{ Achten Sie darauf, daß für Ihre Zahlen jeweils 32 Bit ausreichen. }

program Solve;

  procedure AssemblerExample;

  asm

    mov al, $0ff

  end;

begin

end.


Fehlermeldung "String constant too long "
"String constant too long"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat das Ende des von Ihnen festgelegten Strings nicht gefunden. Häufigster Grund hierfür ist ein falsch gesetztes schließendes Anführungszeichen.


Beispiele

{ Der Inline Assembler kann das Ende des Strings nicht finden, bevor das Ende der Zeile erreicht wird; er berichtet daher, daß der String zu lang ist. }

program Produce;

  procedure AssemblerExample;

  asm

    db 'Hallo Welt. Ich bin eine Inline Assembler-Anweisung

  end;

begin

end.

{ Setzen Sie das fehlende schließende Anführungszeichen, und der Fehler ist behoben. }

program Solve;

  procedure AssemblerExample;

  asm

    db 'Hallo Welt. Ich bin eine Inline Assembler-Anweisung'

  end;

begin

end.


Fehlermeldung "Error in numeric constant "
"Error in numeric constant"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat einen Fehler in einer von Ihnen eingegebenen numerischen Konstante gefunden.


Beispiele

{ Im folgenden Beispiel hat der Inline Assembler erwartet, eine hexadezimale Konstante zu parsen, fand jedoch ein fehlerhaftes Zeichen. }

program Produce;

  procedure AssemblerExample;

  asm

    mov al, $z0f0

  end;

begin

end.

{ Achten Sie darauf, daß die von Ihnen eingegebenen numerischen Konstanten dem Typ entsprechen, den der Inline Assembler zu parsen erwartet. }

program Solve;

  procedure AssemblerExample;

  asm

    mov al, $f0

  end;

begin

end.


Fehlermeldung "Invalid combination of opcode and operands "
"Invalid combination of opcode and operands"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Inline Assembler-Anweisung festgelegt, die nicht korrekt ist.


Beispiele

{ Der Inline Assembler kann das Ergebnis von $f0 * 16 nicht im Register 'al' speichern - das Ergebnis paßt einfach nicht hinein. }

program Produce;

  procedure AssemblerExample;

  asm

    mov al, $0f0 * 16

  end;

begin

end.

{ Achten Sie darauf, daß die Typen der beiden Operanden miteinander kompatibel sind. }

program Solve;

  procedure AssemblerExample;

  asm

    mov al, $0f * 16

  end;

begin

end.


Fehlermeldung "486/487 instructions not enabled "
"486/487 instructions not enabled"

Compiler-Fehlermeldungen

Beschreibung

Diese Inline Assembler-Fehlermeldung sollten Sie nicht erhalten, da die 486-Instruktionen immer aktiviert sind.


Fehlermeldung "Division by zero "
"Division by zero"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler ist auf einen Ausdruck gestoßen, der zu einer Division durch Null führt.


Beispiele

{ Wenn Sie Programmkonstanten anstelle von Konstantenliteralen benutzen, kann es vorkommen, daß der Fehler nicht so offensichtlich ist. }

program Produce;

  procedure AssemblerExample;

  asm

    dw	1000 / 0

  end;

begin

end.

{ Die Lösung liegt wie bei der Programmierung mit höheren Programmiersprachen darin, darauf zu achten, daß keine Division durch Null erfolgt. }

program Solve;

  procedure AssemblerExample;

  asm

    dw	1000 / 10

  end;

begin

end.


Fehlermeldung "Structure field identifier expected "
"Structure field identifier expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Inline Assembler hat einen Bezeichner rechts von einem '.' erkannt; allerdings handelte es sich nicht um ein Feld des auf der linken Seite des '.' angegebenen Datensatzes. Ein häufiger, jedoch schwer zu entdeckender Fehler dieser Art tritt auf, wenn ein Datensatz mit einem Feld 'ch' benutzt wird - der Inline Assembler interpretiert 'ch' immer als Bezeichnung eines Registers.


Beispiele

{ In diesem Beispiel hat der Inline Assembler erkannt, daß 'y' ein gültiger Bezeichner ist, hat jedoch nicht feststellen können, daß 'y' ein Mitglied des Typs 'd' ist. }

program Produce;

type

  Data = record

    X: Integer;

  end;

  procedure AssemblerExample(D: Data; Y: Char);

  asm

    mov	eax, D.Y

  end;

begin

end.

{ Durch Festlegung der korrekten Variablenbezeichnung wird der Fehler beseitigt. }

program Solve;

type

  Data = record

    X: Integer;

  end;

  procedure AssemblerExample(D: Data; Y: Char);

  asm

    mov	eax, D.X

  end;

begin

end.


Fehlermeldung "LOOP/JCXZ distance out of range "
"LOOP/JCXZ distance out of range"

Compiler-Fehlermeldungen

Beschreibung

Sie haben ein LOOP- oder JCXZ-Ziel in Inline Assembler-Programmcode festgelegt, daß sich außerhalb der Wertebereichs befindet. Der Abstand muß im Bereich -128..127 liegen.

Wenn Sie diese Fehlermeldung erhalten, ersetzen Sie LOOP oder JCXZ durch eine Folge von zwei Anweisungen.


Fehlermeldung "Statement expected, but expression of type '<type>' found "
"Statement expected, but expression of type '<type>' found"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler erwartete, eine Anweisung zu finden, stieß jedoch auf einen Ausdruck des angegebenen Typs.


Beispiele

{ In diesem Beispiel erwartet der Compiler, eine Anweisung zu finden, beispielsweise IF, WHILE oder REPEAT, stößt jedoch auf den Ausdruck (3+4). }

program Produce;

var

  A: Integer;

begin

  (3 + 4);

end.

{ Die Lösung hier ist die Zuweisung des Ergebnisses des Ausdrucks (3+4) zur Variable 'a'. Eine andere Lösung wäre, den betreffenden Ausdruck aus dem Quellcode zu entfernen. Die Entscheidung hängt jeweils von der Situation ab. }

program Produce;

var

  A: Integer;

begin

  A := (3 + 4);

end.


Fehlermeldung "Procedure or function name expected "
"Procedure or function name expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Bezeichner festgelegt, der weder eine Prozedur noch eine Funktion in einer exports-Anweisung darstellt.


Beispiele

{ Es ist nicht möglich, Variablen aus einer Object Pascal-Bibliothek zu exportieren, selbst wenn die Variable vom Typ 'procedure' ist. }

library Produce;

var

  Y: procedure;

exports Y;

begin

end.

{ Achten Sie immer darauf, daß alle in einer EXPORTS-Anweisung aufgeführten Bezeichner wirklich Prozeduren darstellen. }

program Solve;

  procedure ExportMe;

  begin

  end;

exports ExportMe;

begin

end.


Fehlermeldung "PROCEDURE or FUNCTION expected "
"PROCEDURE or FUNCTION expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird unter zwei verschiedenen Voraussetzungen erzeugt, aber in beiden Fällen erwartet der Compiler, das Schlüsselwort procedure oder das Schlüsselwort function zu finden.


Beispiele

{ In beiden nachstehenden Fällen sollte nach dem Schlüsselwort 'class' das Wort 'procedure' stehen. }

program Produce;

type

  Base = class

    class AProcedure; { case 1 }

  end;

  class Base.AProcedure; { case 2 }

  begin

  end;

begin

end.

{ Wie deutlich zu sehen ist, wird der Fehler in diesem Programm behoben, wenn das Schlüsselwort 'procedure' hinzugefügt wird. }

program Solve;

type

  Base = class

    class procedure AProcedure;

  end;

  class procedure Base.AProcedure;

  begin

  end;

begin

end.


Fehlermeldung "Instance variable '<name>' inaccessible here "
"Instance variable '<name>' inaccessible here"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie versuchen, einen Bezug auf eine Instanz-Variable aus einer Klassenmethode heraus herzustellen


Beispiele

{ Klassenmethoden besitzen keinen Instanz-Zeiger und können daher nicht auf Methoden oder Instanz-Daten der Klasse zugreifen. }

program Produce;

type

  Base = class

    Title: string;

    class procedure Init;

  end;

  class procedure Base.Init;

  begin

    Self.Title := 'Funktioniert nicht';

    Title := 'Funktioniert nicht';

  end;

begin

end.

{ Die einzige Lösung bei diesem Fehler liegt darin, aus einer Klassenmethode heraus auf keine Mitgliederdaten oder -methoden zuzugreifen. }

program Solve;

type

  Base = class

    Title: string;

    class procedure Init;

  end;

  class procedure Base.Init;

  begin

  end;

begin

end.


Fehlermeldung "EXCEPT or FINALLY expected "
"EXCEPT or FINALLY expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Jeder try-Block block muß entweder einen Teil zur Fehlerbehandlung (except) oder einen zur Code-Bereinigung (finally)enthalten.


Beispiele

{ Im nachstehenden Programmcode fehlt die 'except'- oder 'finally'-Anweisung des Programmcodes der Ausnahmenbehandlung; der Compiler wird daher eine Fehlermeldung ausgeben. }

program Produce;

begin

  try

  end;

end.

{ Durch Hinzufügen der fehlenden Anweisung ist der Compiler in der Lage, die Compilierung des Programmcodes abzuschließen. In diesem Fall ist die vollständige Abarbeitung des Programms mit der Anweisung 'except' möglich. }

program Solve;

begin

  try

  except

  end;

end.


Fehlermeldung "Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause "
"Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Da eine finally-Anweisung von Object Pascals Mechanismus zur Ausnahmenbehandlung oder durch die normale Programmsteuerung aufgerufen und verlassen werden kann, ist es möglich, daß von dem explizite Steuerungsfluß Ihres Programmes abgewichen wird. Wenn finally vom Mechanismus zur Ausnahmenbehandlung aufgerufen wird, kann die Anweisung nicht mit Break, Continue oder Exit verlassen werden - wenn die finally-Anweisung vom System zur Ausnahmenbehandlung ausgeführt wird, muß die Steuerung zum System zur Ausnahmenbehandlung zurückkehren.


Beispiele

{ Im folgenden Programm wird versucht, die finally-Anweisung mit einer break-Anweisung zu verlassen. Diese Art, eine FINALLY-Anweisung zu verlassen, ist nicht zulässig. }

program Produce;

  procedure A0;

  begin

    try

      (* versuchen Sie etwas, das fehlschlagen dürfte *)

    finally

      Break;

    end;

  end;

begin

end.

{ Die einzige Lösung bei diesem Fehler liegt darin, Ihren Programmcode zu restrukturieren, so daß die betreffende Anweisung nicht in der FINALLY-Anweisung erscheint. }

program Solve;

  procedure A0;

  begin

    try

      (* versuchen Sie etwas, das fehlschlagen dürfte *)

    finally

    end;

  end;

begin

end.


Fehlermeldung "'GOTO <label>' leads into or out of TRY statement"
"'GOTO <label>' leads into or out of TRY statement"

Beispiel	Compiler-Fehlermeldungen

Beschreibung

Es ist nicht möglich, mit der goto-Anweisung in eine Ausnahmenbehandlungsanweisung hinein- oder aus dieser hinauszuspringen.

Die ideale Lösung für dieses Problem liegt darin, die Verwendung von goto-Anweisungen konsequent zu vermeiden; wenn dies nicht möglich ist, müssen Sie eine detailliertere Analyse des Programms durchführen, um die beste Vorgehensweise zu ermitteln.


Beispiel

{ Beide GOTO-Anweisungen im folgenden Programmcode sind nicht korrekt. Es ist nicht möglich, in Ausnahmenbehandlungsblöcke hinein- oder aus diesen herauszuspringen. }

program Produce;

label 1, 2;

begin

  goto 1;

  try

1:

  except

    goto 2;

  end;

2:

end.


Fehlermeldung "<clause1> clause expected, but <clause2> found"
"<clause1> clause expected, but <clause2> found"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hatte aufgrund der Pascal-Syntax erwartet, eine <clause1> in Ihrem Programm zu finden, fand jedoch <clause2>.


Beispiele

{ Die erste Deklarierung einer Eigenschaft muß eine Schreib- und eine Lese-Anweisung festlegen, und da beide Anweisungen in der Eigenschaft 'Ch' nicht vorhanden sind, tritt bei der Compilierung ein Fehler auf. Bei Eigenschaften könnte die ursprüngliche Absicht gewesen sein, eine Eigenschaft, die in einer Basisklasse definiert ist, auf eine andere, höhere Sichtbarkeitsebene zu stellen - beispielsweise von öffentlich nach privat. In diesem Fall ist die wahrscheinlichste Ursache für den Fehler darin zu finden, daß die Bezeichnung der Eigenschaft in der Basisklasse nicht gefunden werden konnte. Achten Sie darauf, daß Sie die Bezeichnung der Eigenschaft korrekt geschrieben haben und daß die Eigenschaft sich auch tatsächlich in einer der übergeordneten Klassen befindet. }

program Produce;

type

  CharDesc = class

    vch: Char;

    property Ch: Char;

  end;

end.

{ Die Lösung liegt darin, darauf zu achten, daß alle korrekten Anweisungen gegebenenfalls festgelegt werden. }

program Produce;

type

  CharDesc = class

    vch: Char;

    property Ch: Char read vch write vch;

  end;

end.


Fehlermeldung "Cannot assign to a read-only property "
"Cannot assign to a read-only property"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Eigenschaft, zu der Sie einen Wert zuzuweisen versuchten, hat keine write-Anweisung festgelegt, so daß sie automatisch zu einer Nur-Lese-Eigenschaft geworden ist.


Beispiele

{ Wenn eine Eigenschaft keine 'write'-Anweisung festlegt, wird sie im Endeffekt zu einer Nur-Lese-Eigenschaft; es ist nicht möglich, einer Nur-Lese-Eigenschaft einen Wert zuzuweisen, und daher gibt der Compiler eine Fehlermeldung auf die Zuweisung zu 'c.Title' aus. }

program Produce;

type

  Base = class

    S: string;

    property Title: string read S;

  end;

var

  C: Base;

procedure DiddleTitle

begin

  if C.Title = '' then

    C.Title := 'Supergalaktische Angreifer mit Turbo-Gungla-Waffen';

    { bearbeiten Sie C.Title weiter }

end;

begin

end.

{ Falls Sie über den Quellcode verfügen, liegt eine Lösung darin, für die Nur-Lese-Eigenschaft eine write-Anweisung anzugeben - natürlich kann dies die Semantik der Basisklasse dramatisch ändern und sollte nicht auf die leichte Schulter genommen werden. Eine andere Möglichkeit liegt darin, eine Zwischenvariable einzuführen, die den Wert der Nur-Lese-Eigenschaft enthält - dies ist die zweite im folgenden Programmcode aufgeführte Alternative. }

program Solve;

type

  Base = class

    S: string;

    property Title: string read S;

  end;

var

  C: Base;

procedure DiddleTitle;

var

  Title: string;

begin

  Title := C.Title;

  if Title = '' then

    Title := 'Supergalaktische Angreifer mit Turbo-Gungla-Waffen';

    { bearbeiten Sie Title weiter }

end;

begin

end.


Fehlermeldung "Cannot read a write-only property "
"Cannot read a write-only property"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Eigenschaft, von der aus Sie versuchen, einen Wert zu lesen, hat keine read-Anweisung festgelegt, so daß sie automatisch zu einer Nur-Schreibe-Eigenschaft geworden ist.


Beispiele

{ Da C.Password keine read-Anweisung festgelegt hat, ist es nicht möglich, ihren Wert zu lesen. }

program Produce;

type

  Base = class

    S: string;

    property Password: string write S;

  end;

var

  C: Base;

  S: string;

begin

  S := C.Password;

end.

{ Falls Sie über den Quellcode verfügen, liegt eine einfache Lösung darin, für die Nur-Schreibe-Eigenschaft eine read-Anweisung anzugeben. Dies ist allerdings nicht immer wünschenswert und könnte zu Lücken in einem Sicherheitssystem führen - betrachten Sie beispielsweise eine Nur-Schreibe-Eigenschaft mit der Bezeichnung 'Password', wie in diesem Beispiel: Sie wollen sicherlich nicht zulassen, daß Programme, die diese Klasse benutzen, das gespeicherte Paßwort lesen können. Wenn eine Eigenschaft als Nur-Schreibe-Eigenschaft erstellt wurde, gab es wahrscheinlich einen guten Grund dafür, und Sie sollten erneut untersuchen, warum Sie diese Eigenschaft unbedingt lesen müssen. }

program Solve;

type

  Base = class

    S: string;

    property Password: string read S write S;

  end;

var

  C: Base;

  S: string;

begin

  S := C.Password;

end.


Fehlermeldung "Class already has a default property "
"Class already has a default property"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, einer Klasse eine Standard-Eigenschaft zuzuweisen, die bereits eine Standard-Eigenschaft besitzt.


Beispiele

{ Die Eigenschaft Access im nachstehenden Programmcode versucht, die Standard-Eigenschaft der Klasse zu werden, aber Data wurde bereits als Standard-Eigenschaft festgelegt. Eine Klasse darf nur eine einzige Standard-Eigenschaft besitzen. }

program Produce;

type

  Base = class

    function GetV(I: Integer): Char;

    procedure SetV(I: Integer; const X: Char);

    property Data[I: Integer]: Char read GetV write SetV; default;

    property Access[I: Integer]: Char read GetV write SetV; default;

  end;

function Base.GetV(I: Integer): Char;

begin

  GetV := 'A';

end;

procedure Base.SetV(I: Integer; const X: Char);

begin

end;

begin

end.

{ Die Lösung liegt darin, die falsche Festlegung der Standard-Eigenschaft aus dem Programm zu entfernen. }

program Solve;

type

  Base = class

    function GetV(I: Integer): Char;

    procedure SetV(I: Integer; const X: Char);

    property Data[I: Integer]: Char read GetV write SetV; default;

  end;

function Base.GetV(I: Integer): Char;

begin

  GetV := 'A';

end;

procedure Base.SetV(I: Integer; const X: Char);

begin

end;

begin

end.


Siehe auch

Standard-Eigenschaft

Eigenschaften

Array-Eigenschaften


Fehlermeldung "Operator not applicable to this operand type "
"Operator not applicable to this operand type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird ausgegeben, wenn ein Operator nicht auf die Operanden angewandt werden kann, denen er übergeben wurde - beispielsweise wenn ein Boolescher Operator auf einen Zeiger angewandt wird.


Beispiele

{ Hier war sich ein C++-Programmierer über die Operatorpriorität bei Pascal nicht im klaren; P ist kein Boolescher Ausdruck, und der Vergleich muß in runde Klammern gesetzt werden. }

program Produce;

var

  P: ^Integer;

begin

  if P and P^ > 0 then

    Writeln('P zeigt auf eine Zahl größer 0');

end.

{ Wenn wir P explizit mit nil vergleichen und runde Klammern verwenden, ist der Compiler rundum zufrieden. }

program Solve;

var

  P: ^Integer;

begin

  if (P <> nil) and (P^ > 0) then

    Writeln('P zeigt auf eine Zahl größer 0');

end.


Fehlermeldung "Default property must be an array property "
"Default property must be an array property"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die für die Klasse festgelegte Standard-Eigenschaft ist keine Array-Eigenschaft. Standard-Eigenschaften müssen Array-Eigenschaften sein.


Beispiele

{ Bei der Festlegung einer Standard-Eigenschaft müssen Sie darauf achten, daß sie der Syntax von Array-Eigenschaften entspricht. Die Eigenschaft Data im folgenden Programmcode legt einen Typ Char anstatt eines Arrays fest. }

program Produce;

type

  Base = class

    function GetV: Char;

    procedure SetV(X: Char);

    property Data: Char read GetV write SetV; default;

  end;

function Base.GetV: Char;

begin

  GetV := 'A';

end;

procedure Base.SetV(X: Char);

begin

end;

begin

end.

{ Der Fehler kann behoben werden, indem Sie die Festlegung der betreffenden Eigenschaft in ein Array ändern oder die Anweisung 'default' entfernen. }

program Solve;

type

  Base = class

    function GetV(I: Integer): Char;

    procedure SetV(I: Integer; const X: Char);

    property Data[I: Integer]: Char read GetV write SetV; default;

  end;

function Base.GetV(I: Integer): Char;

begin

  GetV := 'A';

end;

procedure Base.SetV(I: Integer; const X: Char);

begin

end;

begin

end.


Fehlermeldung "TYPEINFO standard function expects a type identifier "
"TYPEINFO standard function expects a type identifier"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, Typinformationen für einen Bezeichner zu erhalten, der keinem Typ zugeordnet ist.


Beispiele

{ Die Standardprozedur TypeInfo benötigt einen Typbezeichner als Parameter. Im folgenden Programmcode ist 'NotType' kein Typbezeichner. }

program Produce;

var

  P: Pointer;

procedure NotType;

begin

end;

begin

  P := TypeInfo(NotType);

end.

{ Sie können diesen Fehler vermeiden, indem Sie darauf achten, daß der für TypeInfo verwendete Parameter ein Typbezeichner ist. }

program Solve;

type

  Base = class

  end;

var

  P: Pointer;

begin

  P := TypeInfo(Base);

end.


Fehlermeldung "Type '<name>' has no type info "
"Type '<name>' has no type info"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, die Standardprozedur TypeInfo auf einen Typbezeichner anzuwenden, mit dem keine Laufzeitinformationen verknüpft sind.


Beispiele

{ Datensatztypen erzeugen keine Typinformationen; diese Verwendung von TypeInfo ist daher unzulässig. }

program Produce;

type

  Data = record

  end;

var

  V: Pointer;

begin

  V := TypeInfo(Data);

end.

{ Eine Klasse erzeugt dagegen RTTI; die Verwendung von TypeInfo an dieser Stelle ist also in jedem Falle zulässig. }

program Solve;

type

  Base = class

  end;

var

  V: Pointer;

begin

  V := TypeInfo(Base);

end.


Fehlermeldung "FOR or WHILE loop executes zero times - deleted "
"FOR or WHILE loop executes zero times - deleted"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat festgestellt, daß die angegebene Schleifenstruktur nicht ein einziges Mal durchlaufen werden wird, und hat sie daher aus Optimierungsgründen gelöscht.


Beispiele

{ Der Compiler stellt fest, daß 'FALSE AND (i < 100)' immer das Ergebnis FALSE hat, und schließt daraus, daß die Schleife nicht durchlaufen werden wird. }

program Produce;

{$HINTS ON}

var

  I: Integer;

begin

  I := 0;

  while False and (I < 100) do

    Inc(I);

end.

{ Die Lösung für diesen Hinweis liegt darin, den Booleschen Ausdruck für die Steuerung von while-Anweisungen zu überprüfen, so daß er nicht immer FALSE ist. Bei for-Schleifen sollten Sie sicherstellen, daß gilt: (Obergrenze - Untergrenze) >= 1. }

program Solve;

{$HINTS ON}

var

  I: Integer;

begin

  I := 0;

  while I < 100 do

    Inc(I);

end.


Fehlermeldung "No definition for abstract method '<name>' allowed "
"No definition for abstract method '<name>' allowed"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben <name> als abstrakt definiert, aber der Compiler hat in der Quelldatei eine Definition für die Methode gefunden. Es ist nicht zulässig, eine Definition für eine abstrakte Deklarierung zu geben.


Beispiele

{ Abstrakte Methoden können nicht definiert werden. Während der Compilierung dieses Programms wird bei Base.Foundation ein Fehler auftreten. }

program Produce;

type

  Base = class

    procedure Foundation; virtual; abstract;

  end;

procedure Base.Foundation;

begin

end;

begin

end.

{ Zur Lösung dieses Fehlers sind zwei Schritte erforderlich. Als erstes müssen Sie die Definition der abstrakten Prozedur entfernen, die in der Basisklasse deklariert ist. Als zweites müssen Sie die Basisklasse erweitern, die abstrakte Prozedur als 'override' in der Erweiterung deklarieren und anschließend eine Definition für die soeben deklarierte Prozedur geben. }

program Solve;

type

  Base = class

    procedure Foundation; virtual; abstract;

  end;

  Derived = class(Base)

    procedure Foundation; override;

  end;

procedure Derived.Foundation;

begin

end;

begin

end.


Fehlermeldung "Method '<name>' not found in base class "
"Method '<name>' not found in base class"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben die Anweisung 'override' auf eine Methode angewandt, aber der Compiler kann keine Prozedur dieser Bezeichnung in der Basisklasse finden.


Beispiele

{ Eine häufige Ursache für diesen Fehler ist ein einfacher Schreibfehler in Ihrem Quellcode. Achten Sie darauf, daß die als 'override'-Prozedur verwendete Bezeichnung genauso wie in der Basisklasse geschrieben wurde. In anderen Situationen wird die Basisklasse nicht die gewünschte Prozedur zur Verfügung stellen; diese Situationen erfordern eine viel eingehendere Analyse, um zu bestimmen, wie dieses Problem gelöst werden kann. }

program Produce;

type

  Base = class

    procedure Title; virtual;

  end;

  Derived = class(Base)

    procedure Titl; override;

  end;

procedure Base.Title;

begin

end;

procedure Derived.Titl;

begin

end;

begin

end.

{ Die Lösung in diesem Beispiel liegt einfach darin, die Schreibweise der Prozedurbezeichnung in Derived zu korrigieren. }

program Solve;

type

  Base = class

    procedure Title; virtual;

  end;

  Derived = class(Base)

    procedure Title; override;

  end;

procedure Base.Title;

begin

end;

procedure Derived.Title;

begin

end;

begin

end.


Fehlermeldung "Invalid message parameter list "
"Invalid message parameter list"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Eine Botschaftenbehandlungsmethode kann nur einen Parameter (var) annehmen; der Parametertyp wird nicht überprüft.


Beispiele

{ Der offensichtliche Fehler im ersten Fall liegt darin, daß der Parameter nicht VAR ist. Der Fehler im zweiten Fall liegt darin, daß mehr als ein Parameter deklariert wurde. }

program Produce;

type

  Base = class

    procedure Msg1(X: Integer); message 151;

    procedure Msg2(var X, Y: Integer); message 152;

  end;

procedure Base.Msg1(X: Integer);

begin

end;

procedure Base.Msg2(var X, Y: Integer);

begin

end;

begin

end.

{ Die Lösung in beiden Fällen ist die Festlegung nur eines einzigen Parameters (var) in der Botschaften-Methoden-Deklarierung. }

program Solve;

type

  Base = class

    procedure Msg1(var X: Integer); message 151;

    procedure Msg2(var Y: Integer); message 152;

  end;

procedure Base.Msg1(var X: Integer);

begin

end;

procedure Base.Msg2(var Y: Integer);

begin

end;

begin

end.


Fehlermeldung "Illegal message method index "
"Illegal message method index"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Wert für Ihren Botschaftenindex festgelegt, der <= 0 ist.


Beispiele

{ Im folgenden Beispiel ist die Festlegung von -151 als Botschaftenindex nicht zulässig. }

program Produce;

type

  Base = class

    procedure Dynamo(var X: Integer); message -151;

  end;

procedure Base.Dynamo(var X: Integer);

begin

end;

begin

end.

{ Achten Sie immer darauf, daß der Wert der Botschaftenindexe >= 1 ist. }

program Solve;

type

  Base = class

    procedure Dynamo(var X: Integer); message 151;

  end;

procedure Base.Dynamo(var X: Integer);

begin

end;

begin

end.


Siehe auch

Botschaftenmethoden

Virtuelle Methoden

Dynamische Methoden


Fehlermeldung "Duplicate message method index "
"Duplicate message method index"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Index für eine dynamische Methode festgelegt, der bereits von einer anderen dynamischen Methode benutzt wird.


Beispiele

{ Die Deklarierung von 'Second' versucht, den gleichen Botschaftenindex zu benutzen wie 'First'; dies ist nicht zulässig. }

program Produce;

type

  Base = class

    procedure First(var X: Integer); message 151;

    procedure Second(var X: Integer); message 151;

  end;

procedure Base.First(var X: Integer);

begin

end;

procedure Base.Second(var X: Integer);

begin

end;

begin

end.

{ Für dieses Problem gibt es zwei einfache Lösungen. Erstens: Wenn Sie wirklich nicht denselben Botschaftenwert verwenden müssen, können Sie die Botschaftennummer so ändern, daß sie eindeutig ist. Zweitens: Sie können eine neue Klasse von der Basisklasse ableiten und das Verhalten des in der Basisklasse deklarierten Botschaften-Handlers überschreiben. Im folgenden Beispiel werden beide Möglichkeiten gezeigt. }

program Solve;

type

  Base = class

    procedure First(var X: Integer); message 151;

    procedure Second(var X: Integer); message 152; { in eindeutigen Index ändern }

  end;

  Derived = class(Base)

    procedure First(var X: Integer); override; { Basisklassenverhalten überschreiben }

  end;

procedure Base.First(var X: Integer);

begin

end;

procedure Base.Second(var X: Integer);

begin

end;

procedure Derived.First(var X: Integer);

begin

end;

begin

end.


Fehlermeldung "Bad file format '<name>' "
"Bad file format '<name>'"

Compiler-Fehlermeldungen

Beschreibung

Die Compiler-Zustandsdatei wurde beschädigt. Es ist nicht möglich, den vorherigen Compiler-Zustand zu laden.


Fehlermeldung "Array type required "
"Array type required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, einen Index in einen Operanden zu setzen, der kein Array ist, oder wenn Sie an einen offenen Array-Parameter ein Argument übergeben, das kein Array ist.


Beispiele

{ Wir versuchen, einen Index auf einen Zeiger auf integer anzuwenden - in C wäre dies zulässig, aber nicht in Pascal. }

program Produce;

var

  P: ^Integer;

  I: Integer;

begin

  Writeln(P[I]);

end.

{ In Pascal müssen wir dem Compiler mitteilen, daß wir P auf ein Array von ganzen Zahlen zeigen lassen wollen. }

program Solve;

type

  TIntArray = array[0..MaxInt div sizeof(Integer)-1] of Integer;

var

  P: ^TIntArray;

  I: Integer;

begin

  Writeln(P^[I])

end.


Fehlermeldung "Inaccessible value "
"Inaccessible value"

Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, einen Wert anzeigen zu lassen, auf den aus dem integrierten Debugger nicht zugegriffen werden kann. Bestimmte Arten von Werten wie ein String vom Typ Variant mit Nullänge können nicht aus dem Debugger heraus angezeigt werden.


Fehlermeldung "Destination cannot be assigned to "
"Destination cannot be assigned to"

Compiler-Fehlermeldungen

Beschreibung

Der integrierte Debugger hat festgestellt, daß Ihre Zuweisung im aktuellen Kontext nicht gültig ist.


Fehlermeldung "Expression has no value "
"Expression has no value"

Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, das Ergebnis eines Ausdrucks, mit dem kein Wert erzeugt wurde, einer Variablen zuzuweisen.


Fehlermeldung "Destination is inaccessible "
"Destination is inaccessible"

Compiler-Fehlermeldungen

Beschreibung

Auf die Adresse, an die Sie einen Wert zu übergeben versuchten, kann aus dem Integrierten Debugger heraus nicht zugegriffen werden.


Fehlermeldung "Expression is not a procedure "
"Expression is not a procedure"

Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, ein Symbol aus Ihrem Programm wie eine Prozedur zu benutzen, obwohl das Symbol keine Prozedur ist.


Fehlermeldung "No source line for this procedure "
"No source line for this procedure"

Compiler-Fehlermeldungen

Beschreibung

Der integrierte Debugger kann keine Quelltextzeile für die angeforderte Prozedur finden.

Falls Sie über den Quellcode verfügen, compilieren Sie die Unit mit der gewünschten Prozedur erneut, und zwar mit aktivierten Debugging-Informationen. Wenn Sie den Quellcode nicht besitzen, gibt es keine Möglichkeit, diese Prozedur anzeigen zu lassen.


Fehlermeldung "Re-raising an exception only allowed in exception handler "
"Re-raising an exception only allowed in exception handler"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben die Syntax der raise-Anweisung benutzt, die für die Neuauslösung einer Ausnahme verwendet wird, aber der Compiler hat festgestellt, daß diese Neuauslösung außerhalb eines Ausnahmenbehandlungsblockes erfolgt ist. Eine Einschränkung des aktuellen Mechanismus zur Ausnahmenbehandlung unterbindet die Neuauslösung von Ausnahmen aus verschachtelten Ausnahmen-Handlern heraus.


Beispiele

{ Es gibt verschiedene Gründe, aus denen dieser Fehler auftreten kann. Erstens: Möglicherweise haben Sie eine Auslösung ohne Ausnahmenkonstruktor außerhalb eines Ausnahmen-Handlers festgelegt. Zweitens: Sie haben eventuell versucht, eine Ausnahme im try-Block eines Ausnahmen-Handlers neu auszulösen. Drittens: Vielleicht haben Sie versucht, die Ausnahme in einem Ausnahmen-Handler neu auszulösen, der in einem anderen Ausnahmen-Handler verschachtelt ist. }

program Produce;

procedure RaiseException;

begin

  raise;            { Fall 1 }

  try

    raise;          { Fall 2 }

  except

    try

      raise;        { Fall 3 }

    except

    end;

    raise;

  end;

end;

begin

end.

{ Eine Lösung dieses Fehlers liegt darin, explizit eine neue Ausnahme auszulösen; dies ist wahrscheinlich in Situationen wie 'Fall 1' und 'Fall 2' anzuraten. In der Situation von 'Fall 3' sollten Sie Ihren Programmcode untersuchen, um eine geeigneten Umweg zu finden, mit dem die gewünschten Ergebnisse erzielt werden können. }

program Solve;

uses SysUtils;

procedure RaiseException;

begin

  raise Exception.Create('Fall 1');

  try

    raise Exception.Create('Fall 2');

  except

    try

      raise Exception.Create('Fall 3');

    except

    end;

    raise;

  end;

end;

begin

end.


Fehlermeldung "Default values must be of ordinal, pointer or small set type "
"Default values must be of ordinal, pointer or small set type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Eigenschaft festgelegt, die eine default-Anweisung enthält, aber die Eigenschaft Typ kann nicht zusammen mit Standardwerten benutzt werden.


Beispiele

{ Das nachstehende Programm erstellt eine Eigenschaft und versucht, ihr einen Standardwert zuzuweisen; da der Typ der Eigenschaft jedoch keine Standardwerte zuläßt, wird eine Fehlermeldung ausgegeben. }

program Produce;

type

  VisualGuage = class

    Pos: Single;

    property Position: Single read Pos write Pos default 0.0;

  end;

begin

end.

{ Wenn dieser Fehler auftritt, gibt es zwei einfache Lösungen: Zum einen kann die Definition des Standardwertes entfernt werden, und zum anderen kann der Typ der Eigenschaft in einen Typ geändert werden, der einen Standardwert zuläßt. Es kann allerdings vorkommen, daß Ihr Programm nicht so einfach in Ordnung zu bringen ist; bedenken Sie den Fall, wenn Sie eine zu große Mengen-Eigenschaft verwenden - in dieser Situation müssen Sie Ihr Programm sorgfältig untersuchen, um die beste Lösung für das Problem feststellen zu können. }

program Solve;

type

  VisualGuage = class

    Pos: Integer;

    property Position: Integer read Pos write Pos default 0;

  end;

begin

end.


Fehlermeldung "Property '<name>' does not exist in base class "
"Property '<name>' does not exist in base class"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler nimmt an, daß Sie versuchen, eine Eigenschaft auf eine andere, höhere Sichtbarkeitsebene in einer abgeleiteten Klasse zu stellen, aber diese Klasse ist in der Basisklasse nicht vorhanden.


Beispiele

{ Für diesen Fehler gibt es zwei Hauptursachen. Zum einen tritt er durch Festlegung einer neuen Eigenschaft ohne Festlegung eines Typs auf; dies wird in der Regel nicht als Verschiebung auf eine andere Sichtbarkeitsebene angesehen. Die zweite Ursache liegt in der Festlegung einer Eigenschaft, die sich in der Basisklasse befinden sollte, aber nicht vom Compiler gefunden werden kann; am häufigsten ist ein Schreibfehler hierfür verantwortlich. Bei der zweiten Ursache gibt der Compiler außerdem Fehlermeldungen aus, daß eine Lese- oder Schreibanweisung erwartet werde. of a proper }

program Produce;

type

  Base = class

  private

    A: Integer;

    property BaseProp: Integer read A write A;

  end;

  Derived = class(Base)

    Ch: Char;

    property Alpha read Ch write Ch; { Fall 1 }

    property BesaProp; { Fall 2 }

  end;

begin

end.

{ Die Lösung im ersten Fall ist die Angabe eines Typs für die Eigenschaft. Im zweiten Fall liegt die Lösung darin, die Schreibweise der Bezeichnung der Eigenschaft zu überprüfen. }

program Solve;

type

  Base = class

  private

    A: Integer;

    property BaseProp: Integer read A write A;

  end;

  Derived = class(Base)

    Ch: Char;

  public

    property Alpha: Char read Ch write Ch; { Fall 1 }

    property BaseProp; { Fall 2 }

  end;

begin

end.


Fehlermeldung "Dynamic method or message handler not allowed here "
"Dynamic method or message handler not allowed here"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dynamische Methoden können nicht als Zugriffsfunktionen für Eigenschaften benutzt werden.


Beispiele

{ Sowohl 'Velocity' als auch 'Value' im nachstehenden Beispiel sind fehlerhaft, da beiden Eigenschaften unzulässige Zugriffsfunktionen zugewiesen wurden. }

program Produce;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer); dynamic;

    function GetV: Integer; message;

    property Velocity: Integer read GetV write V;

    property Value: Integer read V write SetV;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.

{ Als Lösung in diesem Beispiel haben wir die betreffenden Compileranweisungen aus den Deklarierungen der Prozeduren entfernt; dies könnte allerdings in Ihrem speziellen Fall nicht von Nutzen sein. Eventuell müssen Sie die Logik Ihres Programms einer genauen Untersuchung unterziehen, um festzustellen, auf welche Weise Sie am besten Zugriffsfunktionen für die Eigenschaften zur Verfügung stellen können. }

program Solve;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

    property Velocity: Integer read GetV write V;

    property Value: Integer read V write SetV;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := v;

end;

begin

end.


Fehlermeldung "Pointer type required "
"Pointer type required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie den dereferenzierenden Operator '^' auf einen Operanden anwenden, der kein Zeiger ist, und (ein Sonderfall) wenn der zweite Operand in einer Anweisung 'Raise <exception> at <address>' kein Zeiger ist.


Beispiele

{ Obwohl Klassentypen intern als Zeiger auf die eigentlichen Informationen implementiert werden, ist es nicht zulässig, den dereferenzierenden Operator auf Klassentypen auf Quellebene anzuwenden. Dies ist außerdem nicht notwendig - der Compiler wird automatisch eine Dereferenzierung durchführen, wenn diese erforderlich ist. }

program Produce;

var

  C: TObject;

begin

  C^.Destroy;

end.

{ Lassen Sie einfach den dereferenzierenden Operator weg - der Compiler wird automatisch das Richtige tun. }

program Solve;

var

  C: TObject;

begin

  C.Destroy;

end.


Fehlermeldung "Class does not have a default property "
"Class does not have a default property"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Klassen-Instanz-Variable in einem Array-Ausdruck benutzt, aber der Klassentyp hat keine Standard-Array-Eigenschaft deklariert.


Beispiele

{ Im nachstehenden Beispiel wird eine Fehlermeldung ausgelöst, da 'Base' keine Array-Eigenschaft deklariert und 'b' selbst kein Array ist. }

program Produce;

type

  Base = class

  end;

var

  B: Base;

procedure P;

var

  Ch: Char;

begin

  Ch := B[1];

end;

begin

end.

{ Wenn Sie eine Standard-Eigenschaft für eine Klasse deklariert haben, können Sie die Klassen-Instanz-Variable in Array-Ausdrücken verwenden, als wäre die Klassen-Instanz-Variable selbst ein Array. Eine andere Möglichkeit liegt darin, die Bezeichnung der Eigenschaft für den eigentlichen Array-Zugriff zu benutzen. Anmerkung: Wenn die Hinweisfunktion aktiviert ist, erhalten Sie zwei Warnmeldungen mit dem Inhalt, daß der zu 'ch' zugewiesene Wert niemals benutzt werden wird. }

program Solve;

type

  Base = class

    function GetChar(I: Integer): Char;

    property data[I: Integer]: Char read GetChar; default;

  end;

var

  B: Base;

function Base.GetChar(I: Integer): Char;

begin

  GetChar := 'A';

end;

procedure P;

var

  Ch: Char;

begin

  Ch := B[1];

  Ch := B.Data[1];

end;

begin

end.


Fehlermeldung "Bad argument type in variable type array constructor "
"Bad argument type in variable type array constructor"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie versuchen, ein Array mit Hilfe eines Typs zu konstruieren, der für Variablenarrays nicht zulässig ist.


Beispiele

{ Beide Aufrufe von Examiner werden fehlschlagen, weil Aufzählungen und Datensätze in Array-Konstruktoren nicht unterstützt werden. }

program Produce;

type

  Fruit = (apple, orange, pear);

  Data = record

    X: Integer;

    Ch: Char;

  end;

var

  F: Fruit;

  D: Data;

procedure Examiner(V: array of TVarRec);

begin

end;

begin

  Examiner([D]);

  Examiner([F]);

end.

{ In Array-Konstruktoren sind viele Datentypen zulässig, unter anderem die im folgenden Beispiel. }

program Solve;

var

  I: Integer;

  R: Real;

  V: Variant;

procedure Examiner(V: array of TVarRec);

begin

end;

begin

  I := 0; R := 0; V := 0;

  Examiner([I, R, V]);

end.


Fehlermeldung "Could not load RLINK32.DLL "
"Could not load RLINK32.DLL"

Compiler-Fehlermeldungen

Beschreibung

Die Datei RLINK32.DLL konnte nicht gefunden werden. Achten Sie darauf, daß sie sich im angegebenen Verzeichnis befindet.


Fehlermeldung "Wrong or corrupted version of RLINK32.DLL "
"Wrong or corrupted version of RLINK32.DLL"

Compiler-Fehlermeldungen

Beschreibung

Die interne Prüfung auf Übereinstimmung für die Datei RLINK32.DLL ist fehlgeschlagen.

Sie sollten überprüfen, ob Konflikte mit dem PATH bestehen, durch die eine ältere Version der RLINK32 geladen wird. Wenn Sie sicher sind, daß Sie über eine fehlerfreie RLINK32.DLL verfügen, diese Fehlermeldung jedoch immer noch erhalten, wenden Sie sich bitte an Borland International.


Fehlermeldung "';' not allowed before 'ELSE'"
"';' not allowed before 'ELSE'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben ein ';' unmittelbar vor einem else in einer if..else-Anweisung gesetzt. Der Grund hierfür liegt darin, daß das ';' als Anweisungstrennsymbol anstatt als Anweisungsendesymbol behandelt wird - if..else ist eine einzige Anweisung, und ein ';' kann nicht innerhalb dieser Anweisung stehen (gilt nicht für zusammengesetzte Anweisungen).


Beispiele

{ Bei Pascal ist es nicht zulässig, ein ';' unmittelbar vor eine ELSE-Anweisung zu setzen. Im nachstehenden Programmcode wird daher ein Fehler gemeldet. }

program Produce;

var

  B: Integer;

begin

  if B = 10 then

    B := 0;

  else

    B := 10;

end.

{ Für dieses Problem gibt es zwei einfache Lösungen. Die erste Lösung ist die Entfernung des betreffenden ';'. Die zweite Lösung liegt darin, zusammengesetzte Anweisungen für alle Teile der IF..ELSE-Anweisung zu erstellen. Wenn $HINTS aktiviert sind, erhalten Sie einen Hinweis darüber, daß der zu B zugewiesene Wert niemals benutzt wird. statement. }

program Solve;

var

  B: Integer;

begin

  if B = 10 then

    B := 0

  else

    B := 10;

  if B = 10 then

  begin

    B := 0;

  end

  else

  begin

    B := 10;

  end;

end.


Fehlermeldung "Type '<name>' needs finalization - not allowed in variant record "
"Type '<name>' needs finalization - not allowed in variant record"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Bestimmte Typen werden vom Compiler intern auf besondere Weise behandelt: Sie müssen zuerst ordnungsgemäß abgeschlossen werden, damit gegebenenfalls die gesamten von ihnen zur Zeit belegten Ressourcen freigegeben werden. Da der Compiler nicht feststellen kann, welcher Typ während der Programmausführung tatsächlich im Variantenabschnitt eines Datensatzes gespeichert ist, kann nicht garantiert werden, daß diese speziellen Datentypen ordnungsgemäß abgeschlossen werden.


Beispiele

{ String ist einer der Typen, die eine besondere Behandlung vom Compiler erfordern, um die belegten Ressourcen ordnungsgemäß freigeben zu können. Aus diesem Grunde ist die Benutzung von String in einem Variantenabschnitt nicht zulässig. }

program Produce;

type

  Data = record

    case Kind:Char of

    'A': (Str: string);

  end;

begin

end.

{ Eine Lösung für diesen Fehler läge darin, alle betreffenden Deklarierungen aus dem Variantenabschnitt herauszubringen. Eine andere Möglichkeit wäre es, Zeigertypen zu verwenden (beispielsweise ^String) und den Speicher selbst zu verwalten. }

program Solve;

type

  Data = record

    Str: string;

  end;

begin

end.


Fehlermeldung "Type '<name>' needs finalization - not allowed in file type "
"Type '<name>' needs finalization - not allowed in file type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Bestimmte Typen werden vom Compiler intern auf besondere Weise behandelt: Sie müssen zuerst ordnungsgemäß abgeschlossen werden, damit gegebenenfalls die gesamten von ihnen zur Zeit belegten Ressourcen freigegeben werden.

Da der Compiler nicht feststellen kann, wie die Länge einer langen Zeichenkette während der Programmausführung tatsächlich sein wird, kann nicht garantiert werden, daß diese speziellen Datentypen ordnungsgemäß abgeschlossen werden. Datensätze in typisierten Dateien müssen alle dieselbe Größe besitzen, daher sind Typen mit lange Zeichenketten nicht zulässig.


Beispiele

{ String ist einer der Typen, für die ein besonderer Abschluß durchgeführt werden muß, und kann daher nicht in einem Dateityp gespeichert werden. }

program Produce;

type

  Data = record

    Name: string;

  end;

var

  InFile: file of Data;

begin

end.

{ Eine einfache Lösung für String ist die Neudeklarierung des Typs als Array mit Zeichen. In anderen Fällen, in denen ein besonderer Abschluß durchgeführt werden muß, wird es immer schwieriger, eine binäre Dateistruktur mit Standard-Pascal-Merkmalen wie 'file of' aufrechtzuerhalten. In diesen Situationen ist es wahrscheinlich einfacher, spezialisierte Datei-I/O-Routinen zu schreiben. }

program Solve;

type

  Data = record

    Name: array[1..25] of Char;

  end;

var

  InFile: file of Data;

begin

end.


Fehlermeldung "Expression too complicated "
"Expression too complicated"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler ist in Ihrem Quellcode auf einen Ausdruck gestoßen, der für eine Bearbeitung durch den Compiler zu komplex ist.

Vermindern Sie die Komplexität dieses Ausdrucks durch Einführung einiger temporärer Variablen.


Fehlermeldung "Element 0 inaccessible - use 'Length' or 'SetLength' "
"Element 0 inaccessible - use 'Length' or 'SetLength'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Object Pascal-Typ string speichert die Länge des Strings nicht in Element 0. Die alte Methode, die Länge eines Strings durch Zugriff auf Element 0 zu verändern oder abzurufen, funktioniert bei langen Strings nicht.


Beispiele

{ Hier versucht das Programm, die Länge des Strings durch direkten Zugriff auf das erste Element abzurufen. Dies ist nicht zulässig. }

program Produce;

var

  Str: string;

  Len: Integer;

begin

  Str := 'Kojo no tsuki';

  Len := Str[0];

end.

{ Mit den Standard-Prozeduren SetLength und Length erhalten Sie denselben Funktionsumfang wie durch direkten Zugriff auf das erste Element des Strings. Wenn die Hinweisfunktion aktiviert ist, erhalten Sie eine Warnmeldung darüber, daß der Wert von 'len' nicht benutzt wird. }

program Solve;

var

  Str: string;

  Len: Integer;

begin

  Str := 'Kojo no tsuki';

  Len := Length(Str);

end.


Fehlermeldung "System unit out of date or corrupted: missing '<name>' "
"System unit out of date or corrupted: missing '<name>'"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler sucht eine spezielle Funktion, die sich in System.dcu befindet, kann sie jedoch nicht finden. Ihre Unit System ist beschädigt oder veraltet.

Achten Sie darauf, daß in Ihrem Suchpfad für die Bibliotheken keine Konflikte auftreten, die auf eine andere System.dcu zeigen könnten. Versuchen Sie eine Neuinstallation von System.dcu. Wenn keine dieser Lösungen greift, wenden Sie sich bitte an Borland International.


Fehlermeldung "Record, object or class type required "
"Record, Object or class type required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler erwartete, die Typbezeichnung zu finden, mit dem ein Record, ein Objekt oder eine Klasse festgelegt wurde, konnte jedoch keine Typbezeichnung finden.

Für diesen Fehler gibt es zwei mögliche Ursachen: zum einen die Anwendung von '.' auf ein Objekt, das kein Datensatz ist, und zum anderen die Verwendung einer Variable in einer with-Anweisung, die nicht den korrekten Typ aufweist.


Beispiele

{ In diesem Programm gibt es zwei Ursachen für denselben Fehler: zum einen die Anwendung von '.' auf ein Objekt, das kein Datensatz ist, und zum anderen die Verwendung einer Variable in einer WITH-Anweisung, die nicht den korrekten Typ aufweist. }

program Produce;

type

  RecordDesc = class

    Ch: Char;

  end;

var

  pCh: PChar;

  r: RecordDesc;

procedure A;

begin

  pCh.Ch := 'A';    (* Fall 1 *)

  with pCh do

  begin (* Fall 2 *)

  end;

end;

end.

{ Eine einfache Lösung für diesen Fehler liegt darin, stets darauf zu achten, daß '.' und WITH jeweils nur auf Datensätze, Objekte oder Klassenvariablen angewandt werden. }

program Solve;

type

  RecordDesc = class

    Ch: Char;

  end;

var

  R: RecordDesc;

procedure A;

begin

  R.Ch := 'A';    (* Fall 1 *)

  with r do

  begin (* Fall 2 *)

  end;

end;

end.


Fehlermeldung "Type not allowed in OLE Automation call "
"Type not allowed in OLE Automation call"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Wenn ein Datentyp vom Compiler nicht in eine Variante konvertiert werden kann, ist dieser Typ in einem Aufruf der OLE-Automatisierung nicht zulässig.


Beispiele

{ Eine Klasse kann nicht in einen Variant-Typ konvertiert werden und ist daher in einem OLE-Aufruf nicht zulässig. }

program Produce;

type

  Base = class

    X: Integer;

  end;

var

  B: Base;

  V: Variant;

begin

  V.Dispatch(B);

end.

{ Die einzige Lösung für dieses Problem ist die manuelle Konvertierung dieser Datentypen in den Typ Variant bzw. die ausschließliche Verwendung von Datentypen, die automatisch in den Typ Variant konvertiert werden können. }

program Solve;

type

  Base = class

    X: Integer;

  end;

var

  B: Base;

  V: Variant;

begin

  V.Dispatch(B.X);

end.


"<RLink32 error message>"

Compiler-Fehlermeldungen

Beschreibung

RLINK32 ist auf einen Fehler gestoßen, der Ihnen hiermit ordnungsgemäß gemeldet wird.

Eine ausführlichere Beschreibung dieses Fehlers finden Sie im RLINK32-Handbuch.


"<Filename>: <RLink32 error message>"

Compiler-Fehlermeldungen

Beschreibung

RLINK32 ist auf einen Fehler gestoßen, der Ihnen hiermit ordnungsgemäß gemeldet wird.

Eine ausführlichere Beschreibung dieses Fehlers finden Sie im RLINK32-Handbuch.


Fehlermeldung "Too many conditional symbols "
"Too many conditional symbols"

Compiler-Fehlermeldungen

Beschreibung

Sie haben den für bedingte Symbole (einschließlich Konfigurationsdateien) zugewiesenen Speicherplatz überschritten, der in der Befehlszeile definiert wurde. Für alle bedingten Symbole zusammen sind 256 Byte zugewiesen. Jedes bedingte Symbol belegt bei der Speicherung im Bereich „bedingte Symbole“ 1 zusätzliches Byte.

Die einzige Lösung liegt darin, die Anzahl der bedingten Compilierungssymbole in der Befehlszeile (oder in den Konfigurationsdateien) zu verringern.


Fehlermeldung "Method '<name>' hides virtual method of base type '<name>' "
"Method '<name>' hides virtual method of base type '<name>'"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Methode deklariert, die dieselbe Bezeichnung wie eine virtuelle Methode in der Basisklasse besitzt. Diese neue Methode ist keine virtuelle Methode. Der Zugriff auf die Methode der Basisklasse mit derselben Bezeichnung wird daher durch diese Methode verhindert.


Beispiele

{ Beide in der Definition von Derived deklarierten Methoden verbergen die virtuellen Funktionen mit derselben Bezeichnung in der Basisklasse. }

program Produce;

type

  Base = class

    procedure VirtuMethod; virtual;

    procedure VirtuMethod2; virtual;

  end;

  Derived = class(Base)

    procedure VirtuMethod;

    procedure VirtuMethod2;

  end;

procedure Base.VirtuMethod;

begin

end;

procedure Base.VirtuMethod2;

begin

end;

procedure Derived.VirtuMethod;

begin

end;

procedure Derived.VirtuMethod2;

begin

end;

begin

end.

{ Bei der Beseitigung dieses Fehlers stehen zwei Möglichkeiten zur Wahl. Zum einen können Sie ein Überschreiben festlegen und auf diese Weise die Prozedur der abgeleiteten Klasse ebenfalls virtuell machen, so daß vererbte Aufrufe sich immer noch auf die ursprüngliche Prozedur beziehen können. Sie könnten auch die Bezeichnung der Prozedur in der Deklarierung in der abgeleiteten Klasse ändern. In diesem Beispiel werden beide Methoden gezeigt. }

program Solve;

type

  Base = class

    procedure VirtuMethod; virtual;

    procedure VirtuMethod2; virtual;

  end;

  Derived = class(Base)

    procedure VirtuMethod; override;

    procedure Virtu2Method;

  end;

procedure Base.VirtuMethod;

begin

end;

procedure Base.VirtuMethod2;

begin

end;

procedure Derived.VirtuMethod;

begin

end;

procedure Derived.Virtu2Method;

begin

end;

begin

end.


Siehe auch

Überschreiben von Methoden


Hinweismeldung "Variable '<name>' is declared but never used in '<name>' "
"Variable '<name>' is declared but never used in '<name>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben in einer Prozedur eine Variable deklariert, verwenden sie jedoch nicht.


Beispiele

program Produce;

{$HINTS ON}

procedure Local;

var

  I: Integer;

begin

end;

begin

end.

{ Eine einfache Lösung liegt darin, alle unbenutzten Variablen aus Ihren Prozeduren zu entfernen. Unbenutzte Variablen können allerdings auch auf einen Fehler bei der Implementierung Ihres Algorithmus hindeuten. }

program Solve;

{$HINTS ON}

procedure Local;

begin

end;

begin

end.


Fehlermeldung "Compile terminated by user "
"Compile terminated by user"

Compiler-Fehlermeldungen

Beschreibung

Sie haben während einer Compilierung die Schaltfläche Abbrechen im Dialogfeld Compilierung betätigt.


Fehlermeldung "Unnamed arguments must precede named arguments in OLE Automation call g vorangestellt werden"
"Unnamed arguments must precede named arguments in OLE Automation call g vorangestellt werden"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, unbenannte Parameter nach benannten OLE-Automatisierungsparametern zu setzen.


Beispiele

{ Der benannte Parameter FileName muß in dieser OLE-Verteilung nach dem unbenannten Parameter stehen. }

program Produce;

var

  Ole: Variant;

begin

  Ole.Dispatch(FileName:='FrogEggs', 'Tapioca');

end.

{ Die Lösung, die Parameter zu vertauschen, ist am einfachsten, kann sich jedoch für Ihren speziellen Fall als ungeeignet erweisen. Eine andere Möglichkeit liegt darin, dem unbenannten Parameter eine Bezeichnung zu geben. }

program Solve;

var

  Ole: Variant;

begin

  Ole.dispatch('Tapioca', FileName:='FrogEggs');

end.


Fehlermeldung "Abstract methods must be virtual or dynamic "
"Abstract methods must be virtual or dynamic"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Wird eine abstrakte Methode in einer Basisklasse deklariert, muß sie entweder vom normalen virtuellen oder dynamischen virtuellen Typ sein.


Beispiele

{ Die folgende Deklarierung weist einen Fehler auf, da abstrakte Methoden entweder virtuell oder dynamisch sein müssen. }

program Produce;

type

  Base = class

    procedure DaliVision; abstract;

    procedure TellyVision; abstract;

  end;

begin

end.

{ Dieser Fehler kann entfernt werden, indem die Methode als virtuell oder dynamisch festgelegt wird, je nachdem, welcher Typ für Ihre Anwendung am besten geeignet ist. }

program Solve;

type

  Base = class

    procedure DaliVision; virtual; abstract;

    procedure TellyVision; dynamic; abstract;

  end;

begin

end.


Warnmeldung "Case label outside of range of case expression "
"Case label outside of range of case expression"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben innerhalb einer case-Anweisung ein Label angegeben, das von der Steuervariable der Case-Anweisung nicht erzeugt werden kann.


Beispiele

{ Ein TatesCompass kann nicht alle Werte der CompassPoints aufnehmen, und daher werden mehrere der Case-Labels Fehler auslösen. }

program Produce;

{$WARNINGS ON}

type

  CompassPoints = (n, o, s, w, no, so, sw, nw);

  FourPoints = n..w;

var

  TatesCompass: FourPoints;

begin

  TatesCompass := e;

  case TatesCompass of

    n:    Writeln('Nord');

    o:    Writeln('Ost');

    s:    Writeln('West');

    w:    Writeln('Süd');

    no:   Writeln('Nordost');

    so:   Writeln('Südost');

    sw:   Writeln('Südwest');

    nw:   Writeln('Nordwest');

  end;

end.

{ Nach Untersuchung des Programmcodes, um festzustellen, was wirklich beabsichtigt war, stehen zwei Möglichkeiten zur Verfügung. Zum einen kann die Steuervariable der Case-Anweisung geändert werden, damit sie alle Case-Labels erzeugen kann. Die zweite Möglichkeit wäre, alle Case-Labels zu entfernen, die die Steuervariable nicht erzeugen kann. In diesem Beispiel wird die erste Möglichkeit gezeigt. }

program Solve;

{$WARNINGS ON}

type

  CompassPoints = (n, o, s, w, no, so, sw, nw);

  FourPoints = n..w;

var

  TatesCompass: CompassPoints;

begin

  TatesCompass := e;

  case TatesCompass OF

    n:    Writeln('Nord');

    o:    Writeln('Ost');

    s:    Writeln('West');

    w:    Writeln('Süd');

    no:   Writeln('Nordost');

    so:   Writeln('Südost');

    sw:   Writeln('Südwest');

    nw:   Writeln('Nordwest');

end;

end.


Fehlermeldung "Object type required "
"Object type required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn der Compiler einen Objekttyp erwartet. Beispielsweise muß der ursprüngliche Typ eines Objektes ebenfalls ein Objekttyp sein.


Beispiele

{ In der Systemunit ist TObject ein Klassentyp; die Ableitung eines Objekttyps ist daher nicht möglich. }

type

  MyObject = object(TObject)

  end;

begin

end.

{ Achten Sie darauf, daß der Typbezeichner wirklich für einen Objekttyp steht - möglicherweise ist er falsch geschrieben oder wird von einem Bezeichner einer anderen Unit verborgen. }

program Solve;

type

  MyObject = class  { Dies heißt eigentlich: class(TObject) }

  end;

begin

end.


Fehlermeldung "Field or method identifier expected "
"Field or method identifier expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Bezeichner für eine read- oder write-Anweisung auf eine Eigenschaft festgelegt, der weder ein Feld noch eine Methode ist.


Beispiele

{ Beide Eigenschaften in diesem Programmcode erzeugen einen Fehler. Die erste Eigenschaft erzeugt einen Fehler, weil es nicht möglich ist, die Eigenschaft selbst als Lese- und Schreib-Methode festzulegen. Die zweite Eigenschaft erzeugt einen Fehler, weil 'r' kein Mitglied der Basisklasse ist. }

program Produce;

var

  R: string;

type

  Base = class

    T: string;

    property Title: string read Title write Title;

    property Caption: string read R write R;

  end;

begin

end.

{ Um diesen Fehler zu beheben, stellen Sie sicher, daß alle Lese- und Schreibanweisungen für Eigenschaften einen gültigen Feld- oder Methodenbezeichner festlegen, der Mitglied der Klasse ist, die Eigentümer der Eigenschaft ist. }

program Solve;

type

  Base = class

    T: string;

    property Title: string read T write T;

  end;

begin

end.


Fehlermeldung "Constructing instance of '<name>' containing abstract methods "
"Constructing instance of '<name>' containing abstract methods"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der momentan compilierte Programmcode konstruiert Instanzen von Klassen, die abstrakte Methoden enthalten.


Beispiele

{ Eine abstrakte Prozedur existiert nicht; es ist also nicht ungefährlich, Instanzen einer Klasse zu erstellen, die abstrakte Prozeduren enthält. In diesem Fall ist die Erstellung von 'b' die Ursache für die Warnung. Jeder Aufruf von 'Abstraction' während der hier erstellten Instanz von 'b' würde zu einem Laufzeitfehler führen. Es wird ein Hinweis ausgegeben, daß der zu 'b' zugewiesene Wert niemals benutzt wird. }

program Produce;

{$WARNINGS ON}

{$HINTS ON}

type

  Base = class

    procedure Abstraction; virtual; abstract;

  end;

var

  B: Base;

begin

  B := Base.Create;

end.

{ Eine Lösung dieses Problems ist die Entfernung der abstrakten Anweisung aus der Deklarierung der Prozedur, wie hier gezeigt wird. Eine andere Möglichkeit, das Problem anzugehen, läge darin, eine Klasse von Base abzuleiten und dann eine konkrete Version von Abstraction zu geben. Es wird ein Hinweis ausgegeben, daß der zu B zugewiesene Wert niemals benutzt wird. }

program Solve;

{$WARNINGS ON}

{$HINTS ON}

type

  Base = class

    procedure Abstraction; virtual;

  end;

var

  B: Base;

procedure Base.Abstraction;

begin

end;

begin

  B := Base.Create;

end.


Fehlermeldung "Field definition not allowed after methods or properties "
"Field definition not allowed after methods or properties"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, einer Klasse weitere Felder hinzuzufügen, nachdem bereits auf die erste Deklarierung einer Methode oder einer Prozedur gestoßen wurde. Alle Felddefinitionen müssen vor die Methoden und Eigenschaften gestellt werden.


Beispiele

{ Die Deklarierung von 'a' nach 'FirstMethod' löst einen Fehler aus. }

program Produce;

type

  Base = class

   procedure FirstMethod;

    A: Integer;

  end;

procedure Base.FirstMethod;

begin

end;

begin

end.

{ Um diesen Fehler zu beheben, reicht es in der Regel aus, alle Felddefinitionen vor die erste Deklarierung einer Methode oder einer Eigenschaft zu verschieben. }

program Solve;

type

  Base = class

    A: Integer;

    procedure FirstMethod;

  end;

procedure Base.FirstMethod;

begin

end;

begin

end.


Fehlermeldung "Cannot override a static method "
"Cannot override a static method"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben in einer abgeleiteten Klasse versucht, eine Basismethode zu überschreiben, die nicht als einer der virtuellen Typen deklariert war.


Beispiele

{ Im nachstehenden Beispiel wird ein Fehler ausgelöst, weil Base.StaticMethod nicht als virtuelle Methode deklariert wurde und daher eine Überschreibung ihrer Deklaration nicht möglich ist. }

program Produce;

type

  Base = class

    procedure StaticMethod;

  end;

  Derived = class(Base)

    procedure StaticMethod; override;

  end;

procedure Base.StaticMethod;

begin

end;

procedure Derived.StaticMethod;

begin

end;

begin

end.

{ Die einzige Möglichkeit, diesen Fehler aus Ihrem Programm zu entfernen, wenn Sie nicht über den Quellcode für die Basisklassen verfügen, ist die Entfernung der 'override'-Festlegung aus der Deklarierung der abgeleiteten Methode. Falls Sie über den Quellcode der Basisklassen verfügen, könnten Sie unter sorgfältiger Überlegung die Methode der Basisklasse so ändern, daß sie als einer der virtuellen Typen deklariert wird - seien Sie sich jedoch bewußt, daß diese Änderung drastische Auswirkungen auf Ihre Programme haben kann. }

program Solve;

type

  Base = class

    procedure StaticMethod;

  end;

  Derived = class(Base)

    procedure StaticMethod;

  end;

procedure Base.StaticMethod;

begin

end;

procedure Derived.StaticMethod;

begin

end;

begin

end.


Fehlermeldung "Variable '<name>' inaccessible here due to optimization "
"Variable '<name>' inaccessible here due to optimization"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Auswertungs- oder Überwachungsanweisung versucht, den Wert von <name> abzurufen, aber der Compiler konnte feststellen, daß die tatsächliche Lebensdauer der Variablen vor diesem Prüfungszeitpunkt beendet war. Dieser Fehler tritt häufig auf, wenn der Compiler feststellt, daß einer lokalen Variable ein Wert zugewiesen wird, der nach einem bestimmten Punkt im Steuerfluß des Programms nicht mehr benutzt wird.


Beispiele

1.	Erstellen Sie eine neue Anwendung.

2.	Plazieren Sie eine Schaltfläche in das Formular.

3.	Führen Sie einen Doppelklick auf die Schaltfläche aus, um zur 'click'-Methode zu gelangen.

4.	Fügen Sie eine globale Variable C vom Typ Integer zum Implementierungsabschnitt hinzu.

Die Klick-Methode sollte folgendermaßen aussehen:

procedure TForm1.Button1Click(Sender: TObject);

var

  A, B: Integer;

begin

  A := 10;

  B := 20;

  C := B;

  A := C;

end;

5.	Setzen Sie einen bedingten Programmstopp bei der Zuweisung zu C.

6.	Compilieren und starten Sie die Anwendung.

7.	Betätigen Sie die Schaltfläche.

8.	Wenn der bedingte Programmstopp erreicht wird, öffnen Sie den Auswerter (Run|Evaluate/Watch).

9.	Werten Sie A aus.

Der Compiler bemerkt, daß die erste Zuweisung zu A „tot“ ist, da der Wert niemals benutzt wird. Aus diesem Grunde verzögert der Compiler sogar die Benutzung von A, bis die zweite Zuweisung erfolgt - bis zu dem Zeitpunkt, an dem C zu A zugewiesen wird, wird die Variable A als „tot“ erachtet und kann vom Auswerter nicht benutzt werden.

Die einzige Lösung liegt darin, nur Variablen anzeigen zu lassen, für die feststeht, daß sie „lebendige“ Werte enthalten.


Fehlermeldung "Necessary library helper function was eliminated by linker "
"Necessary library helper function was eliminated by linker"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der integrierte Debugger versucht, einige der Compiler-Hilfsfunktionen für die Ausführung der angeforderten Auswertung zu benutzen. Der Linker hat auf der anderen Seite festgestellt, daß die Hilfsfunktion nicht vom Programm benutzt wurde, und hat sie daher nicht mit dem Programm verknüpft.


Beispiele

1	Erstellen Sie eine neue Anwendung.

2.	Plazieren Sie eine Schaltfläche in das Formular.

3.	Führen Sie einen Doppelklick auf die Schaltfläche aus, um zur 'click'-Methode zu gelangen.

4	Fügen Sie eine globale Variable V vom Typ string zum Interface-Abschnitt hinzu.

5	Fügen Sie eine globale Variable P vom Typ PChar zum Interface-Abschnitt hinzu.

Die Klick-Methode sollte folgendermaßen aussehen:

procedure TForm1.Button1Click(Sender: TObject);

begin

  V := 'Initialized';

  P := nil;

  V := 'Abid';

end;

6	Setzen Sie einen bedingten Programmstopp bei der zweiten Zuweisung zu V.

7	Compilieren und starten Sie die Anwendung.

8	Betätigen Sie die Schaltfläche.

9	Wenn der bedingte Programmstopp erreicht wird, öffnen Sie den Auswerter (Run|Evaluate/Watch).

10	Werten Sie V aus.

11	Bringen Sie den Cursor in das Feld 'New Value'.

12	Geben Sie P ein.

13	Wählen Sie Modify.

Der Compiler verwendet eine spezielle Funktion, um ein PChar in einen String zu kopieren. Falls diese spezielle Funktion vom Programm nicht benutzt wird, wird sie zur Verringerung der Größe der erzeugten ausführbaren Datei nicht mit ihr verknüpft. In diesem Fall findet keine Zuweisung eines PChar zu einem String statt, so daß er vom Linker gelöscht wird.

procedure TForm1.Button1Click(Sender: TObject);

begin

  V := 'Initialized';

  P := nil;

  V := 'Abid';

  V := p;

end;

Durch Einbau einer zusätzlichen Zuweisung eines PChar zu einem String wird sicherstellt, daß der Linker die gewünschte Prozedur in das Programm aufnimmt. Wenn Sie während einer Debugging-Sitzung auf diesen Fehler stoßen, deutet dies darauf hin, daß Sie ein Sprachen- oder Umgebungsmerkmal verwenden, das im ursprünglichen Programm nicht gebraucht wurde.


Fehlermeldung "Missing or invalid conditional symbol in '$<symbol>' directive "
"Missing or invalid conditional symbol in '$<symbol>' directive"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Nach den Anweisungen $IFDEF, $IFNDEF, $DEFINE und $UNDEF muß ein Symbol stehen.


Beispiele

{ Die bedingte Anweisung $IFDEF wurde hier nicht ordnungsgemäß festgelegt, so daß ein Fehler ausgelöst wird. }

program Produce;

{$IFDEF}

{$ENDIF}

begin

end.

{ Die Lösung dieses Problems liegt darin, darauf zu achten, daß ein zu testendes Symbol nach der zugehörigen Anweisung steht. }

program Solve;

{$IFDEF WIN32}

{$ENDIF}

begin

end.


Fehlermeldung "Incompatible format specification "
"Incompatible format specification"

Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Formatbezeichner für eine Überwachungs- oder Auswertungsanweisung festgelegt, der mit dem Typ des zu untersuchenden Objektes nicht kompatibel ist. Beispielsweise löst der Versuch, eine Boolesche Variable als String anzeigen zu lassen, diesen Fehler aus.


Fehlermeldung "Format specifier must be C, S, D, H, X, Fn, P, R or nM "
"Format specifier must be C, S, D, H, X, Fn, P, R or nM"

Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, einen unzulässigen Formatbezeichner für den Überwachungs- bzw. Auswertungsausdruck festzulegen.

Sie müssen eine gültige Formatfestlegung erstellen, bevor die Auswertung fortgesetzt werden kann.


Fehlermeldung "Bad specification of M format "
"Bad specification of M format"

Compiler-Fehlermeldungen

Beschreibung

Sie haben einen unzulässigen M-Formatbezeichner festgelegt. Nur C, D, H, X, S und M sind als Zusatz zum M-Bezeichner zulässig.


Fehlermeldung "Object or class type required "
"Objekt oder Klassentyp erforderlich"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn die Syntax 'Typename.Methodname' verwendet wird, die Typbezeichnung sich aber weder auf ein Objekt noch auf einen Klassentyp bezieht.


Beispiele

{ Der Typ Integer weist natürlich keine Create-Methode auf - aber TInteger. }

program Produce;

type

  TInteger = class

    Value: Integer;

  end;

var

  V: TInteger;

begin

  V := Integer.Create;

end.

{ Achten Sie darauf, daß der Bezeichner sich wirklich auf ein Objekt oder auf einen Klassentyp bezieht - möglicherweise ist er falsch geschrieben oder wird von einem Bezeichner einer anderen Unit verborgen. }

program Solve;

type

  TInteger = class

    Value: Integer;

  end;

var

  V: TInteger;

begin

  V := TInteger.Create;

end.


Fehlermeldung "Fn requires 2 <= n <= 18 "
"Fn requires 2 <= n <= 18 1"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben einen Wert festgelegt, der außerhalb des Bereiches des Gleitkomma-Formatbezeichners im integrierten Debugger. liegt.

Der Bereich für den Fn-Formatbezeichner reicht von 2 bis 18.


Beispiele

1	Erstellen Sie eine Anwendung mit einer reellen Variable.

2	Werten Sie diese Variable mit ',F21' am Schluß des Auswertungsbefehls aus (beispielsweise: realVar,F21).

3	Werten Sie f erneut aus, aber legen Sie für den Fn-Bezeichner eine Zahl zwischen 2 und 18 fest.

Bei der Auswertung reeller Zahlen mit Hilfe der Fn-Festlegung muß gelten: 2 <= n <= 18.


Warnmeldung "'<name>' not previously declared as a PROPERTY "
"'<name>' not previously declared as a PROPERTY"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, eine Eigenschaft durch Neudeklarierung auf eine andere, höhere Sichtbarkeitsebene zu stellen, aber <name> in der Basis-Klasse wurde nicht als Eigenschaft deklariert.


Beispiele

{ Der Zweck einer Neudeklarierung von 'Derived.Title' ist es, das Feld zu verändern, das zum Lesen und Schreiben der Eigenschaft 'Title' benutzt wird, und es der höheren 'public' Sichtbarkeit zur Verfügung zu stellen. Leider wollte der Programmierer eigentlich 'TitleProp' benutzen und nicht 'Title'. }

program Produce;

{$WARNINGS ON}

type

  Base = class

  protected

    Caption: string;

    Title: string;

    property TitleProp: string read Title write Title;

  end;

  Derived = class(Base)

  public

    property Title read Caption write Caption;

  end;

begin

end.

{ Dieser Fehler kann auf mehrere Arten angegangen werden. Die erste Möglichkeit, die wahrscheinlich am häufigsten genutzt wird, ist die Festlegung der korrekten zu deklarierenden Eigenschaft. Die zweite Möglichkeit, die in der Neudeklarierung von 'Title' deutlich wird, beseitigt das Problem durch explizite Erstellung einer neuen Eigenschaft mit derselben Bezeichnung wie ein Feld in der Basisklasse. Diese neue Eigenschaft verbirgt das Basisfeld, auf das daher ohne Typumwandlung kein Zugriff mehr möglich ist. (Anmerkung: Wenn die Warnfunktion aktiviert ist, wird mit der Neudeklarierung von 'Title' eine Warnung ausgegeben, mit der Sie davon in Kenntnis gesetzt werden, daß das Mitglied der Basisklasse durch die Neudeklarierung verborgen wird.) }

program Solve;

{$WARNINGS ON}

type

  Base = class

  protected

    Caption: string;

    Title: string;

    property TitleProp: string read Title write Title;

  end;

  Derived = class(Base)

  public

    property TitleProp read Caption write Caption;

    property Title: string read Caption write Caption;

  end;

begin

end.


Fehlermeldung "Field definition not allowed in OLE automation section "
"Field definition not allowed in OLE automation section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, eine Felddefinition in einen OLE-Automatisierungsabschnitt einer Klassendeklarierung zu plazieren. Im Abschnitt automated dürfen nur Eigenschaften und Methoden deklariert werden.


Beispiele

{ Die Deklarierung von I in dieser Klasse löst den Compilierungsfehler aus. }

program Produce;

type

  Base = class

  automated

    I: Integer;

  end;

begin

end.

{ Durch Verschiebung der Deklarierung von I aus dem Automatisierungsabschnitt heraus wird der Fehler behoben. }

program Solve;

type

  Base = class

    I: Integer;

  automated

  end;

begin

end.


Fehlermeldung "Illegal type in OLE automation section: '<typename>' "
"Illegal type in OLE automation section: '<typename>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

<typename> ist im Abschnitt automated nicht zulässig. In Automatisierungsabschnitten ist nur eine begrenzte Auswahl der gültigen Pascal-Typen zulässig.


Beispiele

{ Da der Zeichentyp nicht im Abschnitt 'automated' zulässig ist, löst die Deklarierung von 'Ch' bei der Compilierung einen Fehler aus. }

program Produce;

type

  Base = class

    function GetC: Char;

    procedure SetC(C: Char);

  automated

    property Ch: Char read GetC write SetC dispid 151;

  end;

procedure Base.SetC(C: Char);

begin

end;

function Base.GetC: Char;

begin

  GetC := '!';

end;

begin

end.

{ Für dieses Problem gibt es zwei mögliche Lösungen. Zum einen kann die betreffende Deklarierung aus dem Abschnitt 'automated' herausgebracht werden. Zum anderen kann der betreffende Typ in einen Typ geändert werden, der in einem Abschnitt 'automated' zulässig ist. }

program Solve;

type

  Base = class

    function GetC: string;

    procedure SetC(C: string);

  automated

    property Ch: string read GetC write SetC dispid 151;

  end;

procedure Base.SetC(C: string);

begin

end;

function Base.GetC: string;

begin

  GetC := '!';

end;

begin

end.


Warnmeldung "String constant truncated to fit STRING[<number>] "
" String constant truncated to fit STRING[<number>]"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Eine Stringkonstante wird einer Variablen zugewiesen, die nicht groß genug ist, um den gesamten String aufnehmen zu können. Der Compiler gibt eine Warnung aus, daß das Literal entsprechend der Variablengröße abgeschnitten wurde.


Beispiele

{ Die beiden Stringkonstanten werden Variablen zugewiesen, die zu kurz sind, um den gesamten String aufnehmen zu können. Der Compiler schneidet die Strings ab und führt die Zuweisung durch. }

program Produce;

{$WARNINGS ON}

const

  Title = 'Supergalaktische Angreifer mit Turbo-Gungla-Waffen';

  Subtitle = 'Copyright (c) 1968 by Frank Borland';

type

  TitleString = string[25];

  SubtitleString = string[18];

var

  ProgramTitle: TitleString;

  ProgramSubtitle: SubtitleString;

begin

  ProgramTitle := Title;

  ProgramSubtitle := Subtitle;

end.

{ Für dieses Problem gibt es zwei mögliche Lösungen, die beide in diesem Beispiel erläutert werden. Die erste Lösung ist die Vergrößerung der Variablen, so daß sie den gesamten String aufnehmen kann. Die zweite Möglichkeit liegt darin, die Größe des Strings zu verringern, damit er von der Variablen in ihrer deklarierten Größe aufgenommen werden kann. }

program Solve;

{$WARNINGS ON}

const

  Title = 'Supergalaktische Angreifer mit Turbo-Gungla-Waffen';

  Subtitle = 'Copyright (c) 1968';

type

  TitleString = string[55];

  SubtitleString = string[18];

var

  ProgramTitle: TitleString;

  ProgramSubtitle: SubtitleString;

begin

  ProgramTitle := Title;

  ProgramSubtitle := Subtitle;

end.


Siehe auch

Kurze String-Typen


Fehlermeldung "Constructors and destructors not allowed in OLE automation section "
"Constructors and destructors not allowed in OLE automation section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben unzulässigerweise versucht, einen Konstruktor oder einen Destruktor in den Automatisierungsabschnitt einer Klassendeklarierung zu stellen.


Beispiele

{ Es ist nicht möglich, einen Klassenkonstruktor oder -destruktor im OLE-Automatisierungsabschnitt zu deklarieren. Die Deklarierung des Konstruktors und des Destruktors im nachstehenden Programmcode lösen beide diesen Fehler aus. }

program Produce;

type

  Base = class

  automated

    constructor HardHatBob;

    destructor  DemolitionBob;

  end;

constructor Base.HardHatBob;

begin

end;

destructor Base.DemolitionBob;

begin

end;

begin

end.

{ Die einzige Lösung dieses Fehlers liegt darin, die Deklarierungen aus dem Automatisierungsabschnitt herauszubringen, wie dies in diesem Beispiel geschehen ist. }

program Solve;

type

  Base = class

    constructor HardHatBob;

    destructor  DemolitionBob;

  end;

constructor Base.HardHatBob;

begin

end;

destructor Base.DemolitionBob;

begin

end;

begin

end.


Fehlermeldung "Dynamic methods and message handlers not allowed in OLE automation section E Automatisierungbereich erlaubt"
"Dynamic methods and message handlers not allowed in OLE automation section E Automatisierungbereich erlaubt"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben unzulässigerweise eine dynamische Methode oder eine Botschaften-Methode in einen Automatisierungsbereich einer Klassendeklarierung gestellt.


Beispiele

{ Es ist nicht möglich, eine Deklarierung einer dynamischen Methode oder einer Botschaften-Methode in den OLE-Automatisierungsabschnitt einer Klasse zu stellen. Aus diesem Grunde erzeugen beide Methoden-Deklarierungen im nachstehenden Programmcode einen Fehler. }

program Produce;

type

  Base = class

  automated

    procedure DynaMethod; dynamic;

    procedure MessageMethod(var Msg: Integer); message 151;

  end;

procedure Base.DynaMethod;

begin

end;

procedure Base.MessageMethod;

begin

end;

begin

end.

{ Dieser Fehler kann auf verschiedene Arten aus Ihrem Programm entfernt werden. Als erstes könnten Sie alle Deklarierungen, die diesen Fehler auslösen, aus dem Automatisierungsabschnitt herausbringen, wie dies in diesem Beispiel geschehen ist. Eine andere Möglichkeit läge darin, das Attribut „dynamisch“ oder „Botschaft“ der Methode zu entfernen; dadurch wird natürlich nicht das gewünschte Verhalten der Methode erzielt, aber der Fehler ist behoben. }

program Solve;

type

  Base = class

    procedure DynaMethod; dynamic;

    procedure MessageMethod(var Msg: Integer); message 151;

  end;

procedure Base.DynaMethod;

begin

end;

procedure Base.MessageMethod;

begin

end;

begin

end.


Fehlermeldung "Only register calling convention allowed in OLE automation section "
"Only register calling convention allowed in OLE automation section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine unzulässige Aufrufkonvention für eine Methode festgelegt, die im Abschnitt automated einer Klassendeklarierung erscheint.


Beispiele

{ Die Sprachenspezifikation läßt im OLE-Automatisierungsabschnitt keine Aufrufkonventionen außer 'register' zu. Im nachstehenden Programmcode lautet die betreffende Anweisung 'cdecl'. }

program Produce;

type

  Base = class

  automated

    procedure Method; cdecl;

  end;

procedure Base.Method; cdecl;

begin

end;

begin

end.

{ Für diesen Fehler gibt es drei Lösungsmöglichkeiten. Erstens: Es werden kein Aufrufkonventionen für Methoden festgelegt, die in einem Automatisierungsabschnitt deklariert sind. Zweitens: Es wird nur die Register-Aufrufkonvention festgelegt. Drittens: Die betreffende Deklarierung wird aus dem Automatisierungsabschnitt herausgebracht. }

program Solve;

type

  Base = class

  automated

    procedure Method; register;

    procedure Method2;

  end;

procedure Base.Method; register;

begin

end;

procedure Base.Method2;

begin

end;

begin

end.


Fehlermeldung "Dispid '<number>' already used by '<name>' "
"Dispid '<number>' already used by '<name>'"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Ein Versuch, ein dispid zu benutzen, das bereits einem anderen Mitglied dieser Klasse zugewiesen wurde.


Beispiele

{ Alle Dispide einer automatisierten Eigenschaft müssen eindeutig sein; SecondValue ist daher fehlerhaft. }

program Produce;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

  automated

    property Value: Integer read GetV write SetV dispid 151;

    property SecondValue: Integer read GetV write SetV dispid 151;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.

{ Der Fehler wird behoben, indem SecondValue ein eindeutiges Dispid gegeben wird. }

program Solve;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

  automated

    property Value: Integer read getV write setV dispid 151;

    property SecondValue: Integer read GetV write SetV dispid 152;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.


Siehe auch

OLE-Automatisierung

Eigenschaften


Fehlermeldung "Redeclaration of property not allowed in OLE automation section "
"Redeclaration of property not allowed in OLE automation section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Es ist nicht zulässig, eine Eigenschaft in einem Automatisierungsabschnitt neu zu deklarieren.


Beispiele

{ Im folgenden Beispiel wird Name aus privater Sichtbarkeit in Base mittels Neudeklarierung zu öffentlicher Sichtbarkeit in Derived gebracht. Dieser Vorgang wird für Value wiederholt, führt jedoch zu einem Fehler. }

program Produce;

type

  Base = class

    V: Integer;

    S: string;

  protected

    property Name: string read S write S;

    property Value: Integer read V write V;

  end;

  Derived = class(Base)

  public

    property Name; (* Name mittels Neudeklarierung zu öffentlicher Sichtbarkeit bringen *)

  automated

    property Value;

  end;

begin

end.

{ Es ist einfach nicht möglich, die Sichtbarkeit einer Eigenschaft für einen Automatisierungsabschnitt zu ändern, und daher liegt die Lösung dieses Problems darin, Eigenschaften von Basisklassen nicht in Automatisierungsabschnitten neu zu deklarieren. }

program Solve;

type

  Base = class

    V: Integer;

    S: string;

  protected

    property Name: string read S write S;

    property Value: Integer read V write V;

  end;

  Derived = class(Base)

  public

    property Name; (* Name mittels Neudeklarierung zu öffentlicher Sichtbarkeit bringen *)

    property Value;

  automated

  end;

begin

end.


Fehlermeldung "Undeclared identifier: '<name>' "
"Undeclared identifier: '<name>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler konnte den angegebenen Bezeichner nicht finden - aller Wahrscheinlichkeit nach wurde er während der Deklarierung bzw. während der Benutzung falsch geschrieben. Er könnte zu einer anderen Unit gehören, die keine uses-Anweisung aufweist.


Beispiele

{ Im folgenden Beispiel wurde die Variable als "Counter" deklariert, aber als "Count" benutzt. Die Lösung liegt darin, entweder die Deklarierung zu ändern oder die Stellen zu berichtigen, an denen die Variable benutzt wird. }

program Produce;

var

  Counter: Integer;

begin

  Count := 0;

  Inc(Count);

  Writeln(Count);

end.

{ In diesem Beispiel haben wir uns dafür entschieden, die Deklarierung zu ändern - das war ein geringerer Arbeitsaufwand. }

program Solve;

var

  Count: Integer;

begin

  Count := 0;

  Inc(Count);

  Writeln(Count);

end.


Fehlermeldung "Class type required "
"Class type required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

In bestimmten Situationen erwartet der Compiler einen Klassentyp:

als Vorgänger eines Klassentyps

in der on-Anweisung einer try..except-Anweisung

als erstes Argument einer raise-Anweisung

als letzten Typ eines forward-deklarierten Klassentyps


Beispiele

program Produce;

begin

  raise 'In C++ würde dies funktionieren, aber nicht in Delphi';

end.

program Solve;

uses SysUtils;

begin

  raise Exception.Create('Es gibt allerdings einen unkomplizierten Umweg');

end.


Fehlermeldung "'<clause>' clause not allowed in OLE automation section "
'<clause>' clause not allowed in OLE automation section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Anweisungen index, stored, default und nodefault sind in OLE-Automatisierungsabschnitt nicht zulässig.


Beispiele

{ Die Verwendung einer NODEFAULT-Anweisung mit einer automatisierten Eigenschaft ist nicht zulässig. }

program Produce;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

  automated

    property Value: Integer read GetV write SetV nodefault;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.

{ Der Fehler kann behoben werden, indem die betreffende Anweisung einfach entfernt wird. Eine andere Möglichkeit liegt darin, die Eigenschaft aus dem Automatisierungsabschnitt herauszubringen. }

program Solve;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

  automated

    property Value: Integer read GetV write SetV;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.


Fehlermeldung "Dispid clause only allowed in OLE automation section "
"Dispid clause only allowed in OLE automation section"

Beschreibung

Ein dispid wurde einer Eigenschaft gegeben, die sich nicht in einem Abschnitt automated befindet.


Beispiele

{ Dieses Programm versucht, den Dispid für ein OLE-Automatisierungsobjekt zu setzen, aber die Eigenschaft wurde nicht in einem Automatisierungsabschnitt deklariert. }

program Produce;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

    property Value: Integer read GetV write SetV dispid 151;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.

{ Um diesen Fehler zu beheben, können Sie entweder die Dispid-Anweisung aus der Deklarierung der Eigenschaft entfernen oder die Deklarierung der Eigenschaft in einen Automatisierungsabschnitt bringen. }

program Solve;

type

  Base = class

    V: Integer;

    procedure SetV(X: Integer);

    function GetV: Integer;

  automated

    property Value: Integer read GetV write SetV dispid 151;

  end;

procedure Base.SetV(X: Integer);

begin

  V := X;

end;

function Base.GetV: Integer;

begin

  GetV := V;

end;

begin

end.


Fehlermeldung "Type '<name>' must be a class to have OLE automation "
"Type '<name>' must be a class to have OLE automation"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Objekte älteren Stils können keinen Automatisierungsabschnitt besitzen.


Beispiele

{ Für ein Objekt älteren Stils ist es nicht möglich, einen Automatisierungsabschnitt zu besitzen, und daher wird dieses Beispiel zu einem Fehler führen. }

program Produce;

  type

    OldObject = object

    automated

    end;

begin

end.

{ Der Fehler wird behoben, indem der Typ von 'object' in 'class' geändert oder der Automatisierungsabschnitt entfernt wird. }

program Solve;

  type

    NewClass = class

    automated

    end;

begin

end.


Fehlermeldung "Type '<name>' must be a class to have a PUBLISHED section "
"Type '<name>' must be a class to have a PUBLISHED section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Objekte älteren Stils können keinen Abschnitt published besitzen.


Beispiele

{ Für ein Objekt älteren Stils ist es nicht möglich, einen öffentlichen Abschnitt zu besitzen, und daher wird dieses Beispiel zu einem Fehler führen. }

{$TYPEINFO ON}

program Produce;

  type

    OldObject = object

    published

    end;

begin

end.

{ Der Fehler wird behoben, indem der Typ von 'object' in 'class' geändert oder der öffentliche Abschnitt entfernt wird. }

{$TYPEINFO ON}

program Solve;

  type

    NewClass = class

    published

    end;

begin

end.


Warnmeldung "Redeclaration of '<name>' hides a member in the base class "
"Redeclaration of '<name>' hides a member in the base class"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

In einer Klasse wurde eine Eigenschaft erstellt, die dieselbe Bezeichnung wie eine Variable in einer der Basisklassen besitzt.

Eine mögliche, aber nicht immer offensichtliche Ursache für diesen Fehler liegt darin, daß eine neue Version der Basisklassen-Hierarchie installiert wurde, die neue Mitgliedvariablen aufweist, deren Bezeichnungen mit den Bezeichnungen Ihrer Eigenschaften identisch sind.


Beispiele

{ Derived.v überschreibt, d. h. verbirgt, Base.v; der Zugriff auf Base.v ist ohne Typumwandlung aus keiner Variablen vom Typ Derived möglich. }

{$WARNINGS ON}

program Produce;

type

  Base = class

    V: Integer;

  end;

  Derived = class(Base)

    Ch: Char;

    property V: Char read Ch write Ch;

  end;

begin

end.

{ Der Fehler wird behoben, indem einfach die Bezeichnung der Eigenschaft in der abgeleiteten Klasse geändert wird. }

{$WARNINGS ON}

program Solve;

type

  Base = class

    V: Integer;

  end;

  Derived = class(Base)

    Ch: Char;

    property ChV: Char read Ch write Ch;

  end;

begin

end.


Fehlermeldung "Overriding automated virtual method '<name>' cannot specify a dispid d definieren"
"Overriding automated virtual method '<name>' cannot specify a dispid d definieren"

Beispiele	-Compiler-Fehlermeldungen

Beschreibung

Der während der Deklarierung der ursprünglichen virtuellen Prozedur automated deklarierte dispid muß von allen überschreibenden Prozeduren in den abgeleiteten Klassen benutzt werden.


Beispiele

{ Die überschreibende Deklarierung von Base.Automatic in Derived (Derived.Automatic) versucht unzulässigerweise, einen anderen Dispid für die Prozedur zu definieren. }

program Produce;

type

  Base = class

  automated

    procedure Automatic; virtual; dispid 151;

  end;

  Derived = class(Base)

  automated

    procedure Automatic; override; dispid 152;

  end;

procedure Base.Automatic;

begin

end;

procedure Derived.Automatic;

begin

end;

begin

end.

{ Die Compilierung des Programms wird durchgeführt, wenn die betreffende Dispid-Anweisung entfernt wird. }

program Solve;

type

  Base = class

  automated

    procedure Automatic; virtual; dispid 151;

  end;

  Derived = class(Base)

  automated

    procedure Automatic; override;

  end;

procedure Base.Automatic;

begin

end;

procedure Derived.Automatic;

begin

end;

begin

end.


Fehlermeldung "Published Real property '<name>' must be Single, Double or Extended "
"Published Real property '<name>' must be Single, Double or Extended"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, eine Eigenschaft vom Typ Real zu veröffentlichen; dies ist nicht zulässig. Öffentliche Gleitkomma-Eigenschaften müssen Single, Double oder Extended sein.


Beispiele

{ Die öffentliche Eigenschaft Real im nachstehenden Programm muß entweder entfernt, in einen nichtöffentlichen Abschnitt gebracht oder in einen zulässigen Typ geändert werden. }

program Produce;

  type

    Base = class

    R: Real;

    published

      property RVal: Real read R write R;

    end;

end.

{ Mit dieser Lösung wird die Eigenschaft in einen reellen Typ umgewandelt, mit dem Laufzeit-Typinformationen angezeigt werden. }

program Produce;

  type

    Base = class

    R: Single;

    published

      property RVal: Single read R write R;

    end;

end.


Fehlermeldung "Size of published set '<name>' is >4 bytes "
"Size of published set '<name>' is >4 bytes"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler läßt in einem Abschnitt published keine Mengen zu, die größer als 32 Bit sind. Die Größe einer Menge in Byte kann folgendermaßen berechnet werden: High(setname) div 8 - Low(setname) div 8 + 1.


Beispiele

{$TYPEINFO ON}

program Produce;

  type

    CharSet = set of Char;

    NamePlate = class

    Characters: CharSet;

    published

      property TooBig: CharSet read Characters write Characters ;

    end;

begin

end.

{$TYPEINFO ON}

program Solve;

  type

    CharSet = set of 'A'..'Z';

    NamePlate = class

    Characters: CharSet;

    published

      property TooBig: CharSet read Characters write Characters ;

    end;

begin

end.


Fehlermeldung "Published property '<name>' cannot be of type <type> "
" Published property '<name>' cannot be of type <type>"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Öffentliche Eigenschaften müssen ein Ordinaltyp, Single, Double, Extended oder Comp, ein Stringtyp, ein Mengentyp (der mit 32 Bit auskommt) oder ein Methoden-Zeigertyp sein. Wenn der Compiler in einem öffentlichen Abschnitt auf einen anderen Eigenschaftentyp trifft, entfernt er das Attribut „öffentlich“.


Beispiele

{ Hier wird ein Fehler ausgelöst, da ein Array nicht einer der Datentypen ist, die veröffentlicht werden können. }

{$TYPEINFO ON}

program Produce;

type

  TitleArr = array[0..24] of Char;

  NamePlate = class

    TitleStr: TitleArr;

  published

    property Title: TitleArr read TitleStr write TitleStr;

  end;

begin

end.

{ Dieser Fehler wird vermieden, indem die Deklarierung der Eigenschaft aus dem öffentlichen Abschnitt herausgebracht wird. Eine andere Möglichkeit, wie in diesem Beispiel verwirklicht, liegt darin, den Typ der Eigenschaft in etwas zu verändern, das wirklich veröffentlicht werden kann. }

{$TYPEINFO ON}

program Solve;

type

  TitleArr = Integer;

  NamePlate = class

    TitleStr: TitleArr;

  published

    property Title: TitleArr read TitleStr write TitleStr;

  end;

begin

end.


Fehlermeldung "Thread local variables cannot be local to a function "
"Thread local variables cannot be local to a function"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Thread lokale Variablen müssen mit globalem Gültigkeitsbereich deklariert werden.


Beispiele

{ Eine Thread-Variable kann nicht als lokal zu einer Prozedur deklariert werden. }

program Produce;

  procedure NoTLS;

  threadvar

    X: Integer;

  begin

  end;

begin

end.

{ Zur Vermeidung dieses Fehlers gibt es zwei einfache Möglichkeiten. Zum einen kann der Abschnitt threadvar auf lokalen Gültigkeitsbereich gebracht werden. Zum anderen kann der Abschnitt threadvar in der Prozedur in einen normalen var-Abschnitt geändert werden. Beachten Sie, daß für den Fall, daß die Compiler-Hinweise aktiviert sind, ein Hinweis darüber gegeben wird, daß localX zwar deklariert, aber niemals verwendet wird. }

program Solve;

  threadvar

    X: Integer;

  procedure YesTLS;

    var

      LocalX : Integer;

  begin

  end;

begin

end.


Fehlermeldung "Function needs result type "
"Function needs result type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Funktion deklariert, aber keinen Rückgabetyp festgelegt.


Beispiele

{ Hier soll Sum eine Funktion sein, allerdings haben wir den Compiler nicht darüber unterrichtet. }

program Produce;

function Sum(A: array of Integer);

var

  I: Integer;

begin

  Result := 0;

  for I := 0 to High(A) do

    Result := Result + A[I];

end;

begin

end.

{ Achten Sie einfach darauf, daß Sie einen Ergebnistyp festlegen. }

program Solve;

function Sum(A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := 0;

  for I := 0 to High(A) do

    Result := Result + A[I];

end;

begin

end.


Fehlermeldung "Thread local variables cannot be ABSOLUTE "
"Thread local variables cannot be ABSOLUTE"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Eine Thread lokale Variable kann sich weder auf eine andere Variable beziehen noch auf eine absolute Speicheradresse.


Beispiele

{ Die Anweisung absolute ist im Abschnitt der threadvar-Deklarierung nicht zulässig. }

program Produce;

  threadvar

     SecretNum: Integer absolute $151;

begin

end.

{ Zur Lösung eines Problems dieser Art gibt es zwei einfache Möglichkeiten. Zum einen kann die Anweisung absolute aus dem Abschnitt threadvar entfernt werden. Zum anderen kann die absolute Variable in einen normalen Abschnitt der var-Deklarierung gebracht werden. }

program Solve;

threadvar

  SecretNum: Integer;

var

  sNum: Integer absolute $151;

begin

end.


Fehlermeldung "EXPORTS allowed only at global scope "
"EXPORTS allowed only at global scope"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Im Programm wurde auf eine Anweisung exports mit nichtglobalem Gültigkeitsbereich gestoßen.


Beispiele

{ Eine EXPORTS-Anweisung ist ausschließlich mit globalem Gültigkeitsbereich zulässig. }

program Produce;

  procedure ExportedProcedure;

  exports ExportedProcedure;

  begin

  end;

begin

end.

{ Die Lösung liegt darin, darauf zu achten, daß Ihre EXPORTS-Anweisung globalen Gültigkeitsbereich besitzt und textlich allen in der Anweisung aufgeführten Prozeduren folgt. Allgemein gilt, daß EXPORTS-Anweisungen am besten unmittelbar bevor den Programmcode zur Initialisierung der Quelldatei gestellt werden. }

program Solve;

  procedure ExportedProcedure;

  begin

  end;

exports ExportedProcedure;

begin

end.


Fehlermeldung "Constants cannot be used as open array arguments "
"Constants cannot be used as open array arguments"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Offene Array-Parameter werden für eine Array-Variable, ein konstruiertes Array oder eine einzelne Variable vom Elementtyp des Parameters benötigt.


Beispiele

{ Der Fehler in diesem Beispiel wird ausgelöst, weil ein Stringliteral anstelle des erwarteten Arrays angegeben wurde. Ein Array kann nicht implizit aus einer Konstanten konstruiert werden. }

program Produce;

procedure TakesArray(S: array of string);

begin

end;

begin

  TakesArray('Hallo Fehler ');

end.

{ Mit der Lösung wird der Fehler vermieden, weil das Array explizit konstruiert wird. }

program Solve;

procedure TakesArray(S: array of string);

begin

end;

begin

  TakesArray(['Hallo Fehler']);

end.


Fehlermeldung "Slice standard function only allowed as open array argument "
"Slice standard function only allowed as open array argument"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Es wurde ein Versuch unternommen, ein Array-Slice an ein Array mit fester Größe zu übergeben. Array-Slices können nur an offene Array-Parameter geschickt werden.


Beispiele

{ Im folgenden Beispiel wird der Fehler ausgelöst, weil TakesArray ein Array mit fester Größe erwartet. }

program Produce;

type

  IntegerArray = array[1..10] of Integer;

var

  SliceMe: array[1..200] of Integer;

procedure TakesArray(X: IntegerArray);

begin

end;

begin

  TakesArray(Slice(SliceMe, 5));

end.

{ Im folgenden Beispiel wird der Fehler dagegen nicht ausgelöst, weil TakesArray ein offenes Array als Parameter annimmt. }

program Solve;

type

  IntegerArray = array[1..10] of Integer;

var

  SliceMe: array[1..200] of Integer;

procedure TakesArray(X: array of Integer);

begin

end;

begin

  TakesArray(Slice(SliceMe, 5));

end.


Fehlermeldung "Cannot initialize thread local variables "
"Cannot initialize thread local variables"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler läßt eine Initialisierung von Thread lokalen Variablen nicht zu.


Beispiele

{ Die nachstehende Deklarierung und Initialisierung von 'tls' ist nicht zulässig. }

program Produce;

  threadvar

    tls: Integer = 151;

begin

end.

{ Sie können Thread lokalen Speicherplatz als normal deklarieren und ihn dann im Initialisierungsabschnitt Ihrer Quelldatei initialisieren. }

program Solve;

  threadvar

tls: Integer;

begin

  tls := 151;

end.


Fehlermeldung "Cannot initialize local variables "
"Cannot initialize local variables"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler verbietet die Verwendung von lokalen initialisierten Variablen.


Beispiele

{ Die Deklarierung und Initialisierung von i in der Prozedur Show ist nicht zulässig. }

program Produce;

  var

    J: Integer;

  procedure Show;

  var

    I: Integer = 151;

  begin

  end;

begin

end.

{ Mit Hilfe eines Programmierstils können Sie alle Variablen auf bekannte Werte setzen. }

program Solve;

  var

    J: Integer;

  procedure Show;

  var

    I: Integer;

  begin

    I := 151;

  end;

begin

  J:= 0;

end.


Fehlermeldung "Cannot initialize multiple variables "
"Cannot initialize multiple variables"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Initialisierung von Variablen kann nur durchgeführt werden, wenn die Variablen einzeln deklariert werden.


Beispiele

{ Der Compiler verbietet die Deklarierung und Initialisierung von mehr als einer Variablen zur Zeit. }

program Produce;

  var

    I, J: Integer = 151, 152;

begin

end.

{ Deklarieren Sie einfach jede Variable für sich, damit eine Initialisierung durchgeführt werden kann. }

program Solve;

  var

    I: Integer = 151;

    J: Integer = 152;

begin

end.


Fehlermeldung "Constant object cannot be passed as var parameter "
"Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Da Variablenparameter nur durch die aufgerufene Prozedur oder Funktion geändert werden sollten, können Sie ein Konstantenobjekt nicht an einen Variablenparameter übergeben. Falls Sie lediglich eine umfangreiche Datenstruktur effizient übergeben möchten und die aufgerufene Funktion die Struktur nicht verändern soll, können Sie statt dessen den Parameter const verwenden.


Beispiele

{ In diesem Beispiel besitzt function einen Variablenparameter, aber wir übergeben eine Konstante. }

program Produce;

{$AppType Console}

function Max(var A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := Low(Integer);

  for I := 0 to High(A) do

    if Result < A[I] then

       Result := A[I];

end;

begin

  Writeln( Max([1,2,3]) );   { <-- Hier die Fehlermeldung }

end.

{ Die Lösung liegt darin, den Parameter als Konstantenparameter zu deklarieren (wir wollen ihn schließlich nicht verändern). Eine andere Möglichkeit besteht darin, den Aufruf so zu verändern, daß keine Konstanten übergeben werden. }

program Solve;

{$AppType Console}

function Max(const A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := Low(Integer);

  for I := 0 to High(A) do

    if Result < A[I] then

      Result := A[I];

end;

begin

  Writeln( Max([1,2,3]) );

end.


Fehlermeldung "Invalid function result type "
"Invalid function result type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dateitypen sind ungültige Funktionsergebnisse.


Beispiele

{ Funktionen können keine Dateien liefern. }

program Produce;

function OpenFile(Name: string): file;

begin

end;

begin

end.

{ Die Datei kann als Variablenparameter "zurückgegeben" werden. Alternativ können Sie eine Datei dynamisch allozieren und einen Zeiger darauf zurückgeben. }

program Solve;

procedure OpenFile(Name: string; var F: file);

begin

end;

begin

end.


Fehlermeldung "Procedure cannot have a result type "
"Procedure cannot have a result type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben eine Prozedur deklariert, ihr aber einen Ergebnistyp gegeben. Entweder wollten Sie eigentlich eine Funktion deklarieren, oder Sie sollten den Ergebnistypen löschen.


Beispiele

{ Hier sollte DotProduct eigentlich eine Funktion sein, wir haben nur aus Versehen das falsche Schlüsselwort angegeben... }

program Produce;

procedure DotProduct(const A,B: array of Double): Double;

var

  I: Integer;

begin

  Result := 0.0;

  for I := 0 to High(A) do

    Result := Result + A[I]*B[I];

end;

const

  C: array[1..3] of Double = (1,2,3);

begin

  Writeln( DotProduct(C,C) );

end.

{ Achten Sie einfach darauf, einen Ergebnistypen festzulegen, wenn Sie eine Funktion deklarieren, und keinen Ergebnistypen, wenn Sie eine Prozedur deklarieren. }

program Solve;

function DotProduct(const A,B: array of Double): Double;

var

  I: Integer;

begin

  Result := 0.0;

  for I := 0 to High(A) do

    Result := Result + A[I]*B[I];

end;

const

  C: array[1..3] of Double = (1,2,3);

begin

  Writeln( DotProduct(C,C) );

end.


Warnmeldung "Text after final 'END.' - ignored by compiler "
"Text after final 'END.' - ignored by compiler"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird angezeigt, wenn sich nach dem abschließenden end und dem Punkt, der das logische Ende des Programms bildet, weiterer Quelltext befindet. Wahrscheinlich ist die Verschachtelung von begin..end inkonsistent (irgendwo ist ein 'end' zuviel). Überprüfen Sie, ob der Quelltext wirklich vom Compiler ignoriert werden sollte - möglicherweise ist er recht bedeutend.


Beispiele

program Produce;

begin

end.

//-------------------------------

program Solve;

begin

end.

{ Sie können selbstverständlich Text als Kommentar schreiben - }

{  dadurch wird natürlich keine Warnmeldung ausgelöst          }


Fehlermeldung "Constant expression expected "
"Constant expression expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat an dieser Stelle einen Konstantenausdruck erwartet, der gefundene Ausdruck war jedoch keine Konstante.


Beispiele

{ Der Aufruf von Pos ist für den Compiler kein Konstantenausdruck, auch wenn die Argumente Konstanten sind und Pos im Prinzip während der Compilierung ausgewertet werden könnte. }

program Produce;

const

  Message = 'Hallo, Welt!';

  WPosition = Pos('W', Message);

begin

end.

{ In diesem Fall müssen wir also einfach den rechten Wert für WPosition selbst berechnen. }

program Solve;

const

  Message = 'Hallo, Welt!';

  WPosition = 7;

begin

end.


Fehlermeldung "Constant expression violates subrange bounds "
"Constant expression violates subrange bounds"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler feststellt, daß eine Konstante außerhalb der zulässigen Grenzen liegt. Dies kann beispielsweise dann eintreten, wenn Sie eine Konstante zu einer Variablen vom Typ Untermenge zuweisen.


Beispiele

program Produce;

var

  Digit: 1..9;

begin

  Digit := 0;	{ Botschaft abrufen: Konstantenausdruck verletzt Grenzen der Untermenge }

end.

program Solve;

var

  Digit: 0..9;

begin

  Digit := 0;

end.


Fehlermeldung "Duplicate tag value "
"Duplicate tag value"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn eine Konstante mehr als einmal in der Deklarierung eines Variantendatensatzes erscheint.


Beispiele

program Produce;

type

  VariantRecord = record

    case Integer of

    0: (IntField: Integer);

    0: (RealField: Real);     { <-- Hier die Fehlermeldung }

  end;

begin

end.

program Solve;

type

  VariantRecord = record

    case Integer of

    0: (IntField: Integer);

    1: (RealField: Real);

  end;

begin

end.


Fehlermeldung "Sets may have at most 256 elements "
"Sets may have at most 256 elements"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn Sie versuchen, einen Mengentyp mit mehr als 256 Elementen zu deklarieren. Genauer gesagt müssen die Ober- und die Untergrenze des Basistyps innerhalb von 0 und 255 liegen.


Beispiele

{ In diesem Beispiel besitzt BigSet wirklich nur 256 Elemente, aber auch dies ist unzulässig. }

program Produce;

type

  BigSet = set of 1..256;  { <-- Hier wird die Fehlermeldung ausgegeben }

begin

end.

{ Wir müssen darauf achten, daß die Ober- und die Untergrenze innerhalb von 0 und 255 liegen. }

program Solve;

type

  BigSet = set of 0..255;

begin

end.


Fehlermeldung "<token1> expected but <token2> found "
"<token1> expected but <token2> found"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint bei Syntaxfehlern. Wahrscheinlich ist in der Quelle ein Schreibfehler aufgetreten, oder es wurde etwas ausgelassen. Wenn der Fehler am Beginn einer Zeile erscheint, befindet sich der eigentliche Fehler häufig in der vorangegangenen Zeile.


Beispiele

{ Nach dem Typ Integer erwartet der Compiler ein Semikolon, mit dem die Deklarierung der Variablen abgeschlossen wird. Er findet das Semikolon nicht in der aktuellen Zeile, liest also weiter und findet das Schlüsselwort 'begin' am Anfang der nächsten Zeile. Zu diesem Zeitpunkt weiß der Compiler endgültig, daß etwas nicht stimmt... }

program Produce;

var

  I: Integer

begin               { <-- Hier die Fehlermeldung: ';' erwartet, aber 'BEGIN' gefunden }

end.

{ In diesem Fall fehlte lediglich das Semikolon - ein häufiger Fehler in der Praxis. Im allgemeinen sollten Sie die Zeile genau untersuchen, in der der Fehler aufgetreten ist, und dazu die Zeile darüber, um festzustellen, ob etwas fehlt oder falsch geschrieben wurde. }

program Solve;

var

  I: Integer;       { Semikolon fehlte }

begin

end.


Fehlermeldung "Identifier redeclared: '<name>' "
"Identifier redeclared: '<name>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der angegebene Bezeichner wurde bereits für diesen Gültigkeitsbereich definiert - Sie versuchen, seine Bezeichnung für etwas anderes wiederzuverwenden.


Beispiele

{ Hier ist die Bezeichnung des Programms dieselbe wie die der Variablen - wir müssen eine der Bezeichnungen ändern, um den Compiler zufriedenzustellen. }

program Tests;

var

  Tests: Integer;

begin

end.

program Tests;

var

  TestCnt: Integer;

begin

end.


Fehlermeldung "Duplicate case label "
"Duplicate case label"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn mehr als ein Case-Label mit dem angegebenen Wert in einer Case-Anweisung existiert.


Beispiele

{ Hier haben wir nicht aufgepaßt und den Case-Label 0 zweimal genannt. }

program Produce;

function DigitCount(I: Integer): Integer;

begin

  case Abs(I) of

  0:                    DigitCount := 1;

  0        ..9:         DigitCount := 1;   { <-- Hier die Fehlermeldung }

  10       ..99:        DigitCount := 2;

  100      ..999:       DigitCount := 3;

  1000     ..9999:      DigitCount := 4;

  10000    ..99999:     DigitCount := 5;

  100000   ..999999:    DigitCount := 6;

  1000000  ..9999999:   DigitCount := 7;

  10000000 ..99999999:  DigitCount := 8;

  100000000..999999999: DigitCount := 9;

  else                  DigitCount := 10;

  end;

end;

begin

  Writeln( DigitCount(12345) );

end.

{ Im allgemeinen ist das Problem nicht so einfach zu finden, wenn Sie Symbolkonstanten und Bereiche von Case-Labels verwenden - gegebenenfalls müssen Sie die tatsächlichen Werte der Konstanten notieren, um die Fehlerursache feststellen zu können. }

program Solve;

function DigitCount(I: Integer): Integer;

begin

  case Abs(I) of

  0        ..9:         DigitCount := 1;

  10       ..99:        DigitCount := 2;

  100      ..999:       DigitCount := 3;

  1000     ..9999:      DigitCount := 4;

  10000    ..99999:     DigitCount := 5;

  100000   ..999999:    DigitCount := 6;

  1000000  ..9999999:   DigitCount := 7;

  10000000 ..99999999:  DigitCount := 8;

  100000000..999999999: DigitCount := 9;

  else                  DigitCount := 10;

  end;

end;

begin

  Writeln( DigitCount(12345) );

end.


Fehlermeldung "Label expected "
"Label expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Bezeichner, der in einer goto-Anweisung angegeben oder als Label bei der Inline-Assemblierung verwendet wird, nicht als Label deklariert wurde.


Beispiele

program Produce;

begin

  if 2*2 <> 4 then

    goto Exit; { <-- Hier die Fehlermeldung: Exit ist ebenfalls eine Standard-Prozedur }

  { ... }

Exit:              { Hier weitere Fehlermeldungen }

end.

program Solve;

label

  Exit;            { Labels müssen in Pascal deklariert werden }

begin

  if 2*2 <> 4 then

    goto Exit;

  { ... }

Exit:

end.


Fehlermeldung "For loop control variable must be simple local variable "
"For loop control variable must be simple local variable"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn die Steuervariable einer for-Anweisung keine einfache Variable ist (sondern beispielsweise eine Komponente eines Datensatzes), und wenn sie nicht lokal zu der Prozedur ist, die die for-Anweisung enthält. Aus Gründen der Abwärtskompatibilität ist es zulässig, eine globale Variable als Steuervariable zu verwenden - der Compiler gibt in diesem Fall eine Warnmeldung aus. Beachten Sie, daß mit Verwendung einer lokalen Variable außerdem ein leistungsfähigerer Programmcode erzeugt wird.


Beispiele

program Produce;

var

  I: Integer;

  A: array[0..9] of Integer;

procedure Init;

begin

  for I := Low(A) to High(a) do  { <-- Hier die Warnmeldung }

    A[I] := 0;

end;

begin

  Init;

end.

program Solve;

var

  A: array[0..9] of Integer;

procedure Init;

var

  I: Integer;

begin

  for I := Low(A) to High(a) do

    A[I] := 0;

end;

begin

  Init;

end.


Fehlermeldung "For loop control variable must have ordinal type "
"For loop control variable must have ordinal type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Die Steuervariable einer for-Schleife muß vom Typ Boolean, Char, WideChar oder Integer bzw. ein Aufzählungs- oder ein Untermengentyp sein.


Beispiele

{ In diesem Beispiel wird eine Variable vom Typ Real als Steuervariable für die for-Schleife verwendet; dies ist nicht zulässig. }

program Produce;

var

  X: Real;

begin { Sinuskurve plotten }

  for X := 0 to 2*Pi/0.2 do                            { <-- Hier die Fehlermeldung }

    Writeln( '*': Round((Sin(X*0.2) + 1)*20) + 1 );

end.

{ Der hier am offensichtlichsten zu verwendende Ordinaltyp ist Integer; dieser Typ funktioniert ganz ausgezeichnet. }

program Solve;

var

  X: Integer;

begin { Sinuskurve plotten }

  for X := 0 to Round(2*Pi/0.2) do

    Writeln( '*': Round((Sin(X*0.2) + 1)*20) + 1 );

end.


Fehlermeldung "Types of actual and formal var parameters must be identical "
"Types of actual and formal var parameters must be identical"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Bei einem Variablenparameter muß das eigentliche Argument genau denselben Typ wie der formale Parameter aufweisen.


Beispiele

{ Die Argumente C1 und C2 sind für SwapBytes nicht annehmbar, obwohl sie genau dieselbe Speicherdarstellung und denselben Bereich wie ein Byte aufweisen. }

program Produce;

procedure SwapBytes(var B1, B2: Byte);

var

  Temp: Byte;

begin

  Temp := B1; B1 := B2; B2 := Temp;

end;

var

  C1, C2: 0..255;     { Ähnlich wie ein Byte, aber NICHT identisch }

begin

  SwapBytes(C1,C2);   { <-- Hier die Fehlermeldung }

end.

{ Sie müssen also tatsächlich C1 und C2 als Bytes deklarieren, damit dieses Beispiel compiliert werden kann. }

program Solve;

procedure SwapBytes(var B1, B2: Byte);

var

  Temp: Byte;

begin

  Temp := B1; B1 := B2; B2 := Temp;

end;

var

  C1, C2: Byte;

begin

  SwapBytes(C1,C2);   { <-- Hier die Fehlermeldung }

end.


Fehlermeldung "Too many actual parameters "
"Too many actual parameters"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn beim Aufruf einer Prozedur oder einer Funktion mehr Parameter angegeben werden als von der Prozedur oder Funktion festgelegt.

Außerdem tritt diese Fehlermeldung auf, wenn ein OLE-Automatisierungsaufruf zu viele (mehr als 255) oder zu viele benannte Parameter aufweist.


Beispiele

{ Es wäre praktischer, wenn Max drei Parameter annehmen würde... }

program Produce;

function Max(A,B: Integer): Integer;

begin

  if A > B then Max := A else Max := B

end;

begin

  Writeln( Max(1,2,3) );   { <-- Hier die Fehlermeldung }

end.

{ Normalerweise würden Sie nun site aufrufen, um die korrekte Anzahl von Parametern angeben zu können. Hier haben wir uns dazu entschieden, Ihnen zu zeigen, wie Max mit einer unbegrenzten Zahl von Parametern implementiert werden kann. Beachten Sie, daß der Aufruf von Max nun auf etwas andere Weise erfolgen muß. }

program Solve;

function Max(const A: array of Integer): Integer;

var

  I: Integer;

begin

  Result := Low(Integer);

  for I := 0 to High(A) do

    if Result < A[I] then

      Result := A[I];

end;

begin

  Writeln( Max([1,2,3]) );

end.


Fehlermeldung "Not enough actual parameters "
"Not enough actual parameters"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn beim Aufruf einer Prozedur oder einer Funktion weniger Parameter angegeben werden als in der Deklarierung der Prozedur oder Funktion festgelegt. Dies kann auch bei Aufrufen von Standard-Prozeduren oder -Funktionen der Fall sein.


Beispiele

{ Die Standard-Prozedur Val besitzt einen zusätzlichen Parameter, mit dem ein Fehlercode zurückgegeben werden kann. In diesem Beispiel wurde dieser Parameter nicht angegeben. }

program Produce;

var

  X: Real;

begin

  Val('3.141592', X);	{ <-- Hier die Fehlermeldung }

end.

{ Als typische Reaktion auf diesen Fehler werden Sie den Aufruf mit der Deklarierung der aufgerufenen Prozedur oder mit der Hilfefunktion vergleichen und feststellen, daß Sie einen Parameter vergessen haben, der angegeben werden muß. }

program Solve;

var

  X: Real;

  Code: Integer;

begin

  Val('3.141592', X, Code);

end.


Fehlermeldung "Variable required "
"Variable required"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn Sie versuchen, die Adresse eines Ausdrucks oder einer Konstanten zu benutzen.


Beispiele

{ Eine Konstante wie 1 besitzt keine Speicheradresse; Sie können also weder den Operator @ noch die Standard-Funktion Addr auf diese Konstante anwenden. }

program Produce;

var

  I: Integer;

  PI: ^Integer;

begin

  PI := Addr(1);

end.

{ Sie müssen darauf achten, daß Sie die Adresse der Variablen benutzen. }

program Solve;

var

  I: Integer;

  PI: ^Integer;

begin

  PI := Addr(I);

end.


Fehlermeldung "Declaration of <name> differs from previous declaration "
"Declaration of <name> differs from previous declaration"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn die Deklarierung einer Prozedur, einer Funktion, einer Methode, eines Konstruktors oder eines Destruktors nicht mit der bisherigen (Forward-) Deklarierung übereinstimmt.

Diese Fehlermeldung tritt außerdem auf, wenn Sie versuchen, eine virtuelle Methode zu überschreiben, die überschreibende Methode jedoch eine andere Parameterliste, andere Aufrufkonventionen usw. aufweist.


Beispiele

{ Wie Sie sehen können, gibt es eine ganze Reihe von Ursachen für diese Fehlermeldung. }

program Produce;

type

  MyClass = class

    procedure Proc(Inx: Integer);

    function Func: Integer;

    procedure Load(const Name: string);

    procedure Perform(Flag: Boolean);

    constructor Create;

    destructor Destroy(Msg: string); override;      { <-- Hier die Fehlermeldung }

    class function NewInstance: MyClass; override;  { <-- Hier die Fehlermeldung }

  end;

procedure MyClass.Proc(Index: Integer);             { <-- Hier die Fehlermeldung }

begin

end;

function MyClass.Func: Longint;                     { <-- Hier die Fehlermeldung }

begin

end;

procedure MyClass.Load(Name: string);               { <-- Hier die Fehlermeldung }

begin

end;

procedure MyClass.Perform(Flag: Boolean); cdecl;    { <-- Hier die Fehlermeldung }

begin

end;

procedure MyClass.Create;                           { <-- Hier die Fehlermeldung }

begin

end;

function MyClass.NewInstance: MyClass;              { <-- Hier die Fehlermeldung }

begin

end;

begin

end.

{ Sie müssen die 'previous declaration' sorgfältig mit der Deklarierung vergleichen, die den Fehler ausgelöst hat, um Unterschiede zwischen den beiden Deklarierungen feststellen zu können. }

program Solve;

type

  MyClass = class

    procedure Proc(Inx: Integer);

    function Func: Integer;

    procedure Load(const Name: string);

    procedure Perform(Flag: Boolean);

    constructor Create;

    destructor Destroy; override;                   { Keine Parameter }

    class function NewInstance: TObject; override;  { Ergebnistyp    }

  end;

procedure MyClass.Proc(Inx: Integer);               { Parameterbezeichnung }

begin

end;

function MyClass.Func: Integer;                     { Ergebnistyp   }

begin

end;

procedure MyClass.Load(const Name: string);         { Parameterart }

begin

end;

procedure MyClass.Perform(Flag: Boolean);           { Aufrufkonvention }

begin

end;

constructor MyClass.Create;                         { Konstructor }

begin

end;

class function MyClass.NewInstance: TObject;        { Klassenfunktion }

begin

end;

begin

end.


Fehlermeldung "Illegal character in input file: '<Char>' (<Hexadecimal value>) "
" Illegal character in input file: '<Char>' (<Hexadecimal value>)"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat ein Zeichen gefunden, das in Pascal-Programmen nicht zulässig ist. Diese Fehlermeldung wird am häufigsten durch Fehler im Zusammenhang mit Stringkonstanten und Kommentaren ausgelöst.


Beispiele

{ Hier fiel ein Programmierer in C++-Gewohnheiten zurück und umschloß einen String mit doppelten Anführungszeichen. }

program Produce;

begin

  Writeln("Hallo, Welt!");	{ <-- Hier die Fehlermeldungen }

end.

{ Die Lösung liegt darin, einfache Anführungszeichen zu benutzen. Im allgemeinen müssen Sie das unzulässige Zeichen löschen. }

program Solve;

begin

  Writeln('Hallo, Welt!');	{ In Pascal einfache Anführungszeichen erforderlich }

end.


Fehlermeldung "'<name>' is not a type identifier "
"'<name>' is not a type identifier"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler die Bezeichnung eines Typs erwartet hat, die gefundene Bezeichnung jedoch nicht für einen Typ steht.


Beispiele

{ In diesem Beispiel wird unzulässigerweise die Bezeichnung der Variablen anstatt der Bezeichnung des Typs als Typ des Argumentes verwendet. }

program Produce;

type

  TMyClass = class

    Field: Integer;

  end;

var

  MyClass: TMyClass;

procedure Proc(C: MyClass);	{ <-- Hier die Fehlermeldung }

begin

end;

begin

end.

{ Achten Sie darauf, daß der betreffende Bezeichner wirklich ein Typ ist - möglicherweise ist er falsch geschrieben, oder ein anderer Bezeichner mit derselben Bezeichnung verbirgt den Bezeichner, auf den Sie sich beziehen wollten. }

program Solve;

type

  TMyClass = class

    Field: Integer;

  end;

var

  MyClass: TMyClass;

procedure Proc(C: TMyClass);

begin

end;

begin

end.


Fehlermeldung "File not found: <Filename> "
"File not found: <Filename>"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler eine Eingabedatei nicht finden kann. Es kann sich hierbei um eine Quelldatei, eine compilierte Unit-Datei (Datei .dcu), eine Include-Datei, eine Objektdatei oder eine Ressourcendatei handeln. Überprüfen Sie die Schreibweise der Bezeichnung und den entsprechenden Suchpfad.


Beispiele

program Produce;

uses SysUtis;       { <-- Hier die Fehlermeldung }

begin

end.

program Solve;

uses SysUtils;      { Behobener Schreibfehler }

begin

end.


Fehlermeldung "Could not create output file <Filename> "
"Could not create output file <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler konnte eine Ausgabedatei nicht erstellen. Es kann sich hierbei um eine compilierte Unit-Datei (Datei .dcu), eine ausführbare Datei, eine Map-Datei oder eine Objektdatei handeln. Die Ursachen mit der größten Wahrscheinlichkeit sind ein nicht vorhandenes Verzeichnis und eine schreibgeschützte Datei bzw. Diskette.


Fehlermeldung "Seek error on <Filename> "
"Seek error on <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler ist bei einer Eingabe- oder Ausgabedatei auf einen Suchfehler gestoßen. Dieser Fall sollte niemals eintreten - falls doch, ist die Ursache mit größter Wahrscheinlichkeit in beschädigten Daten zu finden.


Fehlermeldung "Read error on <Filename> "
"Read error on <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler ist bei einer Eingabedatei auf einen Lesefehler gestoßen. Dieser Fall sollte niemals eintreten - falls doch, ist die Ursache mit größter Wahrscheinlichkeit in beschädigten Daten zu finden.


Fehlermeldung "Write error on <Filename> "
"Write error on <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler ist während des Schreibens auf eine Ausgabedatei auf einen Schreibfehler gestoßen. Aller Wahrscheinlichkeit nach ist die Kapazität der Ausgabediskette erschöpft.


Fehlermeldung "Close error on <Filename> "
"Close error on <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Der Compiler ist beim Schließen einer Eingabe- oder Ausgabedatei auf einen Fehler gestoßen. Dieser Fall sollte nur selten eintreten; wenn er eintritt, ist die Ursache mit größter Wahrscheinlichkeit eine volle oder fehlerhafte Diskette.


Fehlermeldung "Bad file format: <Filename> "
"Bad file format: <Filename>"

Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt ein, wenn eine Objektdatei, die mit einer $L- oder einer $LINK-Anweisung geladen wurde, nicht das korrekte Format aufweist.

Es müssen mehrere Einschränkungen berücksichtigt werden:

Schlagen Sie in der Hilfedatei die Einschränkungen hinsichtlich der Vergabe von Segmentbezeichnungen nach

Nicht mehr als 10 Segmente

Nicht mehr als 255 externe Symbole

Nicht mehr als 50 lokale Bezeichnungen in LNAMES-Datensätzen

LEDATA- und LIDATA-Datensätze müssen in Offset-Reihenfolge sein

In FIXU32-Datensätzen werden keine THREAD-Unterdatensätze unterstützt

Nur 32-Bit-Offsets können repariert werden

Nur Segment-Fixups und rückbezügliche Fixups

Ziel eines Fixups muß ein Segment, eine Gruppe oder eine EXTDEF sein

Objekt muß eine 32-Bit-Objektdatei sein

Verschiedene interne Konsistenzbedingungen, die nur fehlschlagen sollten, wenn die Objektdatei beschädigt ist.


Fehlermeldung "Out of memory "
"Out of memory"

Compiler-Fehlermeldungen

Beschreibung

Dem Compiler steht kein freier Speicherplatz mehr zur Verfügung. Dieser Fall sollte nur selten eintreten; wenn er eintritt, sollten Sie sicherstellen, daß Ihre Auslagerungsdatei groß genug ist und trotzdem noch Platz auf der Diskette verbleibt.


Fehlermeldung "Circular unit reference to <Unitname> "
"Circular unit reference to <Unitname>"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Eine oder mehrere Units benutzen sich in ihren Interface-Abschnitten gegenseitig. Da der Compiler den Interface-Abschnitt einer Unit übersetzen muß, damit andere Units diesen Abschnitt benutzen können, muß der Compiler eine Reihenfolge für die Compilierung der Interface-Abschnitte der Units finden können. Überprüfen Sie, ob wirklich alle Units in der uses-Anweisung notwendig sind und ob vielleicht einige der Units statt dessen in den Implementierungsabschnitt einer Unit verschoben werden könnten.


Beispiele

{ Das Problem wird hervorgerufen, weil A und B sich in ihren Interface-Abschnitten gegenseitig benutzen. }

unit A;

interface

uses B;           { A benutzt B, und B benutzt A }

implementation

end.

unit B;

interface

uses A;

implementation

end.

{ Sie können diesen Kreislauf durchbrechen, indem Sie eine oder mehrere uses-Anweisungen in den Implementierungsabschnitt bringen. }

unit A;

interface

uses B;          { Reihenfolge der Compilierung: B.interface, A, B.implementation }

implementation

end.

unit B;

interface

implementation

uses A;          { In den Implementierungsabschnitt verschoben }

end.


Fehlermeldung "Bad unit format: <Filename> e
"Bad unit format: <Filename> e>"

Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn eine compilierte Unit-Datei (Datei .dcu) nicht das korrekt Format aufweist. Aller Wahrscheinlichkeit nach wurde die .dcu-Datei beschädigt. Compilieren Sie diese Datei erneut, oder führen Sie eine Neuinstallation von Object Pascal durch.


Fehlermeldung "PACKED not allowed here "
"PACKED not allowed here"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Das Schlüsselwort packed ist nur für Mengen-, Array-, Datensatz-, Objekt-, Klassen- und Dateitypen zulässig. Im Gegensatz zur 16-Bit-Version wirkt sich packed auf das Layout von Datensatz-, Objekt- und Klassentypen aus.


Beispiele

{ Packed kann nicht auf einen reellen Typ angewandt werden - wenn Sie Speicherplatz sparen möchten, müssen Sie den kleinsten reellen Typ, den Typ Single, verwenden. }

program Produce;

type

  SmallReal = packed Real;

begin

end.

program Solve;

type

  SmallReal = Single;

begin

end.


Fehlermeldung "Label declaration not allowed in interface part "
"Label declaration not allowed in interface part"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn Sie ein Label im Interface-Abschnitt einer Unit deklarieren.


Beispiele

{ Es ist einfach nicht zulässig, ein Label im Interface-Abschnitt einer Unit zu deklarieren. }

unit Produce;

interface

label 99;

implementation

begin

99:

end.

{ Sie müssen das Label in den Implementierungsabschnitt verschieben. }

unit Solve;

interface

implementation

label 99;

begin

99:

end.


Fehlermeldung "Statements not allowed in interface part "
"Statements not allowed in interface part"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Im Interface-Abschnitt einer Unit dürfen sich nur Deklarierungen befinden, keine Anweisungen. Verschieben Sie die Prozedurblöcke in den Implementierungsabschnitt.


Beispiele

{ Wir konnten uns nicht mehr zurückhalten und haben MyProc ein Blockrecht im Interface-Abschnitt verliehen. }

unit Produce;

interface

procedure MyProc;

begin                { <-- Hier die Fehlermeldung }

end;

implementation

begin

end.

{ Wir müssen den Block in den Implementierungsabschnitt verschieben - dann ist alles in Ordnung. }

unit Solve;

interface

procedure MyProc;

implementation

procedure MyProc;

begin

end;

begin

end.


Fehlermeldung "Unit <Unit1> was compiled with a different version of <Unit2> "
"Unit <Unit1> was compiled with a different version of <Unit2>"

Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn die im Interface-Abschnitt einer Unit vorgenommene Deklarierung von symbol sich geändert hat und der Compiler nicht in der Lage ist, eine Unit erneut zu compilieren, die von dieser Deklarierung abhängt, weil der Quellcode nicht zur Verfügung steht.

Hierfür gibt es mehrere Lösungsmöglichkeiten: Compilieren Sie Unit1 erneut (vorausgesetzt, daß Sie über den Quellcode verfügen); verwenden Sie eine ältere Version von Unit2, oder verändern Sie Unit2; beschaffen Sie sich eine neue Version von Unit1 von jemandem, der über den Quellcode verfügt.


Fehlermeldung "Unterminated string "
"Unterminated string"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat kein schließendes Apostroph am Ende eines Zeichen-Strings gefunden.

Beachten Sie, daß Zeichen-Strings nicht in der folgenden Zeile fortgesetzt werden können - Sie können allerdings mit Hilfe des Operators + zwei Zeichen-Strings in getrennten Zeilen miteinander verketten.


Beispiele

{ Wir haben einfach das schließende Anführungszeichen beim String vergessen - nichts Besonderes, passiert ständig. }

program Produce;

begin

  Writeln('Hallo, Welt!);   { <-- Hier die Fehlermeldung - }

end.

{ Also setzen wir das schließende Anführungszeichen, und der Compiler ist rundum zufrieden. }

program Solve;

begin

  Writeln('Hello world!');

end.


Fehlermeldung "Syntax error in real number "
"Syntax error in real number"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt ein, wenn der Compiler den Beginn eines Exponentenfaktors (das Zeichen 'E' oder 'e') in einer Zahl findet, diesem Zeichen aber keine Ziffern folgen.


Beispiele

{ In diesem Beispiel haben wir nach '3.0E' ein Leerzeichen gesetzt - für den Compiler ist die Zahl hier abgeschlossen; die Zahl ist daher unvollständig. }

program Produce;

const

  SpeedOfLight = 3.0E 8;    { <-- Hier die Fehlermeldung }

begin

end.

{ Wir könnten einfach die Leerstelle löschen, aber wir haben ein '+'-Zeichen eingefügt, weil es ein wenig hübscher aussieht. }

program Solve;

const

  SpeedOfLight = 3.0E+8;

begin

end.


Fehlermeldung "Prozedur zu groß: 32K überschritten"
"Prozedur zu groß: 32K überschritten"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird vom Intel-Prozessor nicht benutzt.


Fehlermeldung "Illegal type in Write/Writeln statement "
"Illegal type in Write/Writeln statement"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn Sie einen unzulässigen Typ in einer Write- oder einer Writeln-Anweisung auszugeben versuchen.


Beispiele

{ Es wäre viel praktischer, eine writeln-Anweisung für die Ausgabe von Color zu verwenden, nicht wahr? }

program Produce;

type

  TColor = (rot,grün,blau);

var

  Color: TColor;

begin

  Writeln(Color);

end.

{ Leider ist dies nicht zulässig, und wir müssen ein zusätzliches Array verwenden. }

program Solve;

type

  TColor = (rot,grün,blau);

var

  Color: TColor;

const

  ColorString: array[TColor] of string = ('rot', 'grün', 'blau');

begin

  Writeln(ColorString[Color]);

end.


Fehlermeldung "Illegal type in Read/Readln statement "
"Illegal type in Read/Readln statement"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn Sie eine Variable in einer Read- oder Readln-Anweisung zu lesen versuchen, die keinem gültigen Typ entspricht. Überprüfen Sie den Typ der Variable, und achten Sie darauf, daß Sie keinen dereferenzierenden, indizierenden oder feldauswählenden Operator auslassen.


Beispiele

{ Variablen eines Aufzählungstyps können nicht direkt gelesen werden. }

program Produce;

type

  TColor = (rot,grün,blau);

var

  Color: TColor;

begin

  Readln(Color);     { <-- Hier die Fehlermeldung }

end.

{ Die Lösung liegt darin, einen String zu lesen und diesen String in einer zusätzlichen Tabelle nachzuschlagen. Im obigen Beispiel haben wir uns nicht die Mühe gemacht, eine Fehlerüberprüfung durchzuführen - jeder String wird als 'blau' angesehen. In der Praxis würden wir wahrscheinlich eine Fehlermeldung ausgeben lassen und den Anwender um Wiederholung der Aktion bitten. }

program Solve;

type

  TColor = (rot,grün,blau);

var

  Color: TColor;

  InputString: string;

const

  ColorString: array[TColor] of string = ('rot', 'grün', 'blau');

begin

  Readln(InputString);

  Color := red;

  while (color < blau) and (ColorString[color] <> InputString) do

    Inc(color);

end.


Fehlermeldung "Strings may have at most 255 elements "
"Strings may have at most 255 elements"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn Sie einen kurzen String-Typ mit mehr als 255 Elementen erstellen, ein Stringliteral von mehr als 255 Zeichen einer Variablen vom Typ ShortString zuweisen oder in einem einzigen Zeichen-String mehr als 255 Zeichen haben.

Beachten Sie, daß Sie lange Stringliterale, die über mehr als eine Zeile reichen, mit Hilfe des Operators '+' zur Verkettung von mehreren Stringliteralen konstruieren können.


Beispiele

{ Im nachstehenden Beispiel liegt die Länge des Strings gerade über der Grenze. }

program Produce;

var

  LongString: string[256];  { <-- Hier die Fehlermeldung }

begin

end.

{ Die bequemste Lösung ist die Verwendung der neuen langen Strings - in diesem Fall müßten Sie sich nicht einmal Gedanken über eine vernünftige Maximallänge machen. }

program Solve;

var

  LongString: AnsiString;

begin

end.


Fehlermeldung "Unexpected end of file in comment started on line <Number> "
"Unexpected end of file in comment started on line <Number>"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn Sie einen Kommentar öffnen, aber nicht wieder schließen. Beachten Sie, daß ein Kommentar, der mit '{' beginnt, mit '}' geschlossen werden muß, und ein Kommentar, der mit '(*' beginnt, mit '*)' zu schließen ist.


Beispiele

{ Also wird in diesem Beispiel der Kommentar einfach nicht geschlossen. }

program Produce;

{ Lassen Sie uns hier einen Kommentar beginnen, aber das Schließen vergessen

begin

end.

{ Das Problem wird eben durch Schließen behoben. }

program Solve;

{ Lassen Sie uns hier einen Kommentar beginnen und das Schließen nicht vergessen }

begin

end.


Fehlermeldung "Constant or type identifier expected "
"Constant or type identifier expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler einen Typ erwartet, aber ein Symbol findet, daß weder eine Konstante ist (mit einer Konstante könnte ein Untermengentyp beginnen) noch ein Typbezeichner.


Beispiele

{ Hier ist ExceptionClass eine Variable, kein Typ. }

program Produce;

var

  C: ExceptionClass; { ExceptionClass ist in System eine Variable }

begin

end.

{ Sie müssen sicherstellen, daß ein Typ festgelegt wird. Möglicherweise ist der Bezeichner falsch geschrieben oder wird von einem anderen Bezeichner, beispielsweise in einer anderen Unit, verborgen. }

program Solve;

var

  C: Exception; { Exception ist ein Typ in SysUtils }

begin

end.


Fehlermeldung "Invalid compiler directive: <Directive> "
"Invalid compiler directive: <Directive>"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung bedeutet, daß in einer Compiler-Anweisung oder in einer Befehlszeilenoption ein Fehler aufgetreten ist.

Im folgenden werden einige mögliche Fehlersituationen aufgezeigt:

Eine externe Deklarierung war syntaktisch nicht korrekt.

Eine Befehlszeilenoption oder eine Option in einer DCC32.CFG-Datei wurde vom Compiler\  nicht erkannt oder war ungültig. Beispielsweise ist '-$M100' ungültig, weil die\  Mindeststackgröße 1024 beträgt.

Der Compiler hat eine $XXXXX-Anweisung gefunden, konnte sie aber nicht erkennen. Sie war  wahrscheinlich falsch geschrieben.

Der Compiler hat eine $ELSE- oder eine $ENDIF-Anweisung gefunden, aber keine vorangehende $IFDEF-,\  $IFNDEF- oder $IFOPT-Anweisung.

Nach {$IFOPT} stand keine Schalter-Option und kein + oder -.

Nach der Langform einer Schalteranweisung stand kein ON oder OFF.

Nach einer Anweisung, die einen numerischen Parameter aufnimmt, stand keine gültige Zahl.

Nach der $DESCRIPTION-Anweisung stand kein String.

Nach der $APPTYPE-Anweisung stand weder CONSOLE noch GUI.

Nach der $ENUMSIZE-Anweisung (Kurzform $Z) stand weder 1 noch 2 noch 4.


Beispiele

{ In diesem Beispiel werden drei typische Fehlersituationen gezeigt, wobei die letzten beiden Fehler dadurch verursacht werden, daß der Compiler $If nicht erkannt hat. }

{$Description Copyright Borland International 1996}    { <-- Hier ein Fehler }

program Produce;

{$ApType Console}                                      { <-- Hier ein Fehler }

begin

{$If O+}                                               { <-- Hier ein Fehler }

  Writeln('Optimierungen sind ON');

{$Else}                                                { <-- Hier ein Fehler }

  Writeln('Optimierungen sind OFF');

{$Endif}                                               { <-- Hier ein Fehler }

  Writeln('Hallo, Welt!');

end.

{ $Description erfordert also einen String in Anführungszeichen, wir müssen $AppType korrekt schreiben, und die Überprüfung der Optionen wird mit $IfOpt durchgeführt. Mit diesen Verbesserungen kann das Beispiel ohne Schwierigkeiten compiliert werden. }

{$Description 'Copyright Borland International 1996'}  { String erforderlich }

program Solve;

{$AppType Console}                                     { AppType }

begin

{$IfOpt O+}                                            { IfOpt }

  Writeln('Optimierungen sind ON');

{$Else}                                                { Jetzt in Ordnung }

  Writeln('Optimierungen sind OFF');

{$Endif}                                               { Jetzt in Ordnung }

  Writeln('Hallo, Welt!');

end.


Fehlermeldung "Bad global symbol definition: '<name>' in object file '<Filename>' "
"Bad global symbol definition: '<name>' in object file '<Filename>'"

Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird ausgegeben, wenn eine mit einer $L- oder $LINK-Anweisung verknüpfte Objektdatei eine Definition für ein Symbol enthält, das in Pascal nicht als Prozedur external deklariert worden ist, sondern als etwas anderes (beispielsweise als Variable). Die Definition im Objekt wird in diesem Fall ignoriert.


Fehlermeldung "Ungültige Relozierungsinformation"
"Ungültige Relozierungsinformation"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird zur Zeit nicht benutzt.


Fehlermeldung "Class or object types only allowed in type section "
"Class or object types only allowed in type section"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Klassen- oder Objekttypen müssen immer mit einer expliziten Typdeklarierung in einem Typabschnitt deklariert werden - im Gegensatz zu Datensatztypen können sie nicht unbenannt bleiben. Der Hauptgrund hierfür liegt darin, daß Sie keine Möglichkeit hätten, die Methoden dieses Typs zu deklarieren - schließlich gibt es keine Typbezeichnung.


Beispiele

{ Im nachstehenden Beispiel wird versucht, einen Klassentyp innerhalb einer Deklarierung einer Variablen zu deklarieren - dies ist nicht zulässig. }

program Produce;

var

  MyClass: class

    Field: Integer;

  end;

begin

end.

{ Die Lösung liegt einfach darin, eine Typdeklarierung für den Klassentyp einzuführen. Eine andere Möglichkeit wäre es, den Klassentyp in einen Datensatztypen zu ändern. }

program Solve;

type

  TMyClass = class

    Field: Integer;

  end;

var

  MyClass: TMyClass;

begin

end.


Fehlermeldung "Local class or object types not allowed "
"Local class or object types not allowed"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Klasse und Objekt können nicht lokal zu einer Prozedur deklariert werden.


Beispiele

{ MyProc versucht, einen Klassentyp lokal zu deklarieren; dies ist nicht zulässig. }

program Produce;

  procedure MyProc;

  type

    TMyClass = class

      Field: Integer;

    end;

  begin

  { ... }

  end;

begin

end.

{ Die Lösung liegt einfach darin, die Deklarierung des Klassen- oder Objekttyps auf lokalen Gültigkeitsbereich zu bringen. }

program Solve;

  type

    TMyClass = class

      Field: Integer;

    end;

  procedure MyProc;

  begin

  { ... }

  end;

begin

end.


Fehlermeldung "Virtual constructors are not allowed "
"Virtual constructors are not allowed"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Im Gegensatz zu Klassentypen dürfen Objekttypen nur statische Konstruktoren besitzen.


Beispiele

{ Im nachstehenden Beispiel wird versucht, einen virtuellen Konstruktor zu deklarieren; dies ist bei Objekttypen nicht sonderlich sinnvoll und daher unzulässig. }

program Produce;

type

  TMyObject = object

    constructor Init; virtual;

  end;

constructor TMyObject.Init;

begin

end;

begin

end.

{ Die Lösung liegt darin, den Konstruktor statisch zu machen oder einen Klassentyp neueren Stils zu benutzen, der einen virtuellen Konstruktor besitzen darf }

program Solve;

type

  TMyObject = object

    constructor Init;

  end;

constructor TMyObject.Init;

begin

end;

begin

end.


Fehlermeldung "Could not compile used unit '<Unitname>' "
"Could not compile used unit '<Unitname>'"

Compiler-Fehlermeldungen

Beschreibung

Dieser schwere Fehler wird angezeigt, wenn eine Unit, die von einer anderen Unit mit der uses-Anweisung benutzt wird, nicht compiliert werden konnte. In diesem Fall gibt der Compiler die Compilierung der abhängigen Unit auf, da als Konsequenz aller Wahrscheinlichkeit nach eine große Anzahl von Fehlern auftreten würden.


Fehlermeldung "Left side cannot be assigned to "
"Left side cannot be assigned to"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, ein Nur-Lese-Objekt wie eine Konstante, einen Konstantenparameter oder den Rückgabewert einer Funktion zu bearbeiten versuchen.


Beispiele

{ In diesem Beispiel werden Zuweisungen zu einem Konstantenparameter, zu einer Konstante und zum Ergebnis eines Funktionsaufrufes vorgenommen. Alle Zuweisungen sind nicht zulässig. }

program Produce;

const

  C = 1;

procedure P(const S: string);

begin

  S := 'changed';            { <--Hier die Fehlermeldung }

end;

function F: PChar;

begin

  F := 'Hello';              { OK - der Rückgabewert wird gesetzt }

end;

begin

  C := 2;                    { <-- Hier die Fehlermeldung }

  F := 'h';                  { <-- Hier die Fehlermeldung }

end.

{ Für diese Art Problem gibt es zwei Lösungsmöglichkeiten: Entweder ändern Sie die Definition des Ziels der Zuweisung, so daß die Zuweisung zulässig wird, oder Sie löschen die Zuweisung. }

program Solve;

var

  C: Integer = 1;           { Verwenden Sie eine initialisierte Variable }

procedure P(var S: string);

begin

  S:= 'geändert';            { Verwenden Sie einen Variablenparameter }

end;

function F: PChar;

begin

  F:= 'Hallo';              { Das ist in Ordnung - wir setzen den Rückgabewert }

end;

begin

  C := 2;

  F^ := 'h';                 { Dies kann compiliert werden, wird aber während der Programmausführung zum Absturz führen }

end.


Fehlermeldung "Unsatisfied forward or external declaration: '<Procedurename>' "
"Unsatisfied forward or external declaration: '<Procedurename>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn Sie eine Forward- oder External-Deklarierung einer Prozedur oder Funktion besitzen oder eine Deklarierung einer Methode in einem Klassen- oder Objekttyp und Sie diese Prozedur, Funktion bzw. Methode nirgendwo deklariert haben. Möglicherweise ist die Funktion wirklich nicht vorhanden, oder es liegt einfach daran, daß die Bezeichnung nicht korrekt geschrieben wurde.

Beachten Sie, daß eine Deklarierung einer Prozedur oder einer Funktion im Interface-Abschnitt einer Unit gleichwertig mit einer Forward-Deklarierung ist - Sie müssen die Implementierung (den Block der Prozedur oder der Funktion) im Implementierungsabschnitt zur Verfügung stellen. Auch die Deklarierung einer Methode in einem Klassen- oder Objekttyp ist gleichwertig mit einer Forward-Deklarierung.


Beispiele

{ Die Definition von Sum weist einen leicht aufzufindenden Schreibfehler auf - im Echtfall ist es sehr wahrscheinlich, daß dieser Schreibfehler nicht so offensichtlich ist - bei ein paar tausend Zeilen zwischen der Forward-Deklarierung und der Definition einer Prozedur. }

program Produce;

type

  TMyClass = class

    constructor Create;

  end;

function Sum(const A: array of Double): Double; forward;

function Summ(const A: array of Double): Double;

var

  I: Integer;

begin

  Result := 0.0;

  for I:= 0 to High(A) do

    Result := Result + A[I];

end;

begin

end.

{ Sie müssen also nur darauf achten, daß die Definitionen Ihrer Prozeduren, Funktionen und Methoden alle existieren und korrekt geschrieben sind. }

program Solve;

type

  TMyClass = class

    constructor Create;

  end;

constructor TMyClass.Create;

begin

end;

function Sum(const A: array of Double): Double; forward;

function Sum(const A: array of Double): Double;

var

  I: Integer;

begin

  Result := 0.0;

  for I:= 0 to High(A) do

Result := Result + A[I];

end;

begin

end.


Fehlermeldung "Missing operator or semicolon "
"Missing operator or semicolon"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn zwischen zwei Unterausdrücken kein Operator steht oder zwischen zwei Anweisungen das Semikolon fehlt. Häufig fehlt ein Semikolon in der vorangegangenen Zeile.


Beispiele

{ In der ersten Anweisung in diesem Beispiel befinden sich zwei Fehler - es fehlen ein '+'-Operator und ein Semikolon. Der erste Fehler wird in dieser Anweisung gemeldet, der zweite in der folgenden Zeile. }

program Produce;

var

  I: Integer;

begin

  I := 1 2                 { <-- Hier die Fehlermeldung }

  if I = 3 then            { <-- Hier die Fehlermeldung }

    Writeln('Prima')

end.

{ Die Lösung liegt darin, darauf zu achten, daß alle notwendigen Operatoren und Semikola vorhanden sind. }

program Solve;

var

  I: Integer;

begin

  I := 1 + 2;              { Hier fehlte ein '+'-Operator und ein Semikolon }

  if I = 3 then

    Writeln('Prima')

end.


Siehe auch

Zusammengesetzte Anweisungen


Fehlermeldung "Incompatible types "
"Incompatible types"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler zwei Typen als kompatibel miteinander erwartet hat (d. h. sehr ähnlich zueinander), sie sich aber als unterschiedlich herausgestellt haben. Dieser Fehler tritt in vielen verschiedenen Situationen auf - beispielsweise wenn eine read- oder eine write-Anweisung in einer Eigenschaft eine Methode angibt, deren Parameterliste nicht zu der Eigenschaft paßt, und wenn ein Parameter für eine Standard-Prozedur oder -Funktion nicht vom korrekten Typ ist.


Beispiele

{ Die Standard-Funktion Hi erwartet ein Argument vom Typ Integer oder Word, wir haben aber statt dessen ein Array gegeben. }

program Produce;

var

  A: array[0..9] of Char;

  I: Integer;

begin

  I:= Hi(A);

end.

{ Wir wollten eigentlich die Standard-Funktion High benutzen, nicht Hi. }

program Solve;

var

  A: array[0..9] of Char;

  I: Integer;

begin

  I:= High(A);

end.


Fehlermeldung "Missing parameter type "
"Missing parameter type"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn in einer Parameterliste kein Typ für einen Wertparameter angegeben wird. Bei Konstanten- und Variablenparametern ist das Auslassen des Typs zulässig.


Beispiele

{ Wir wollten, daß die Prozedur P zwei ganzzahlige Parameter besitzt, aber wir haben ein Semikolon anstelle eines Kommas nach dem ersten Parameter gesetzt. Die Funktion ComputeHash sollte einen nichttypisierten ersten Parameter besitzen, aber nichttypisierte Parameter müssen Variablen- oder Konstantenparameter sein - Wertparameter sind nicht möglich. }

program Produce;

procedure P(I;J: Integer);                            { <-- Hier die Fehlermeldung }

begin

end;

function ComputeHash(Buffer; Size: Integer): Integer; { <-- Hier die Fehlermeldung }

begin

end;

begin

end.

{ Die Lösung in diesem Fall lag darin, den Typ in der Parameterliste von P festzulegen und den Parameter Buffer von ComputeHash als Konstantenparameter zu deklarieren, weil wir ihn schließlich nicht verändern wollen. }

program Solve;

procedure P(I,J: Integer);

begin

end;

function ComputeHash(const Buffer; Size: Integer): Integer;

begin

end;

begin

end.


Fehlermeldung "Illegal reference to symbol '<name>' in object file '<Filename>' "
"Illegal reference to symbol '<name>' in object file '<Filename>'"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird ausgegeben, wenn eine Objektdatei, die mit einer $L- oder einer $LINK-Anweisung geladen wurde, einen Bezug auf ein Pascal-Symbol enthält, das keine Prozedur, Funktion, Variable, typisierte Konstante oder Thread lokale Variable ist.


Fehlermeldung "Line too long (more than 255 characters) "
" Line too long (more than 255 characters)"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn die Länge einer Zeile in der Quelldatei 255 Zeichen überschreitet. In der Regel können Sie diese lange Zeile in zwei kürzere Zeilen aufteilen.

Wenn Sie eine wirklich lange String-Konstante benötigen, können Sie diese in mehrere Teile in aufeinanderfolgenden Zeilen aufteilen, die Sie dann mit dem Operator '+' verketten.


Fehlermeldung "Unknown directive: '<Directive>' "
"Unknown directive: '<Directive>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn der Compiler in der Deklarierung einer Prozedur oder einer Funktion auf eine unbekannte Anweisung stößt. Die Anweisung ist wahrscheinlich falsch geschrieben, oder es fehlt ein Semikolon.


Beispiele

{ In der Deklarierung von P ist die Aufrufkonvention falsch geschrieben. In der Deklarierung von Q und GetLastError fehlt jeweils ein Semikolon. }

program Produce;

procedure P; stcall;

begin

end;

procedure Q forward;

function GetLastError: Integer external 'kernel32.dll';

begin

end.

{ Die Lösung liegt darin, darauf zu achten, daß alle Anweisungen korrekt geschrieben sind und alle notwendigen Semikola vorhanden sind. }

program Solve;

procedure P; stdcall;

begin

end;

procedure Q; forward;

function GetLastError: Integer; external 'kernel32.dll';

begin

end.


Fehlermeldung "This type cannot be initialized "
"This type cannot be initialized"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dateitypen (einschließlich des Typs Text) und der Typ Variant können nicht initialisiert werden. Das bedeutet, daß Sie keine typisierten Konstanten oder initialisierten Variablen dieser Typen deklarieren können.

Hinweis	Um die Kompatibilität mit älteren Versionen von Delphi und Borland Pascal zu gewährleisten, unterstützt Object Pascal eine Compileranweisung, mit der Zuweisungen zu typisierten Konstanten zulässig sind. Zur Aktivierung schreibbarer typisierter Konstanten setzen Sie die $J-Anweisung auf {$J+} oder {$WRITEABLECONSTS ON}.


Beispiele

{ Im nachstehenden Beispiel wird versucht, eine initialisierte Variable vom Typ Variant zu deklarieren; dies ist nicht zulässig. }

program Produce;

var

  V: Variant = 0;

begin

end.

{ Die Lösung liegt einfach darin, eine normale Variable mit einer Zuweisungsanweisung zu initialisieren. }

program Solve;

var

  V: Variant;

begin

  V := 0;

end.


Fehlermeldung "Number of elements differs from declaration "
"Number of elements differs from declaration"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn Sie eine typisierte Konstante oder eine initialisierte Variable vom Typ Array deklarieren, aber nicht die entsprechende Anzahl von Elementen angeben.


Beispiele

{ In diesem Beispiel wird ein Array mit 10 Elementen deklariert, aber während der Initialisierung werden nur 9 Elemente angegeben. }

program Produce;

var

  A: array[1..10] of Integer = (1,2,3,4,5,6,7,8,9);

begin

end.

{ Wir mußten einfach das fehlende Element angeben, um den Compiler zufriedenzustellen. Bei der Initialisierung von größeren Arrays kann manchmal nur schwer festgestellt werden, ob die korrekte Anzahl von Elementen angegeben worden ist. Zur Erleichterung können Sie das Layout der Quelldatei so anlegen, daß die Elemente leicht gezählt werden können (beispielsweise zehn Elemente pro Zeile), oder Sie können den Index eines Elements in einem Kommentar neben das Element stellen. }

program Solve;

var

  A: array[1..10] of Integer = (1,2,3,4,5,6,7,8,9,10);

begin

end.


Fehlermeldung "Label already defined: '<Labelname>' "
"Label already defined: '<Labelname>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn ein Label in mehr als einer Anweisung gesetzt ist.


Beispiele

{ In diesem Beispiel wird einfach versucht, Label 1 zweimal zu setzen. }

program Produce;

label 1;

begin

1:

  goto 1;

1:	  { <-- Hier die Fehlermeldung }

end.

{ Achten Sie darauf, daß jedes Label nur jeweils einmal gesetzt wird. }

program Solve;

label 1;

begin

1:

  goto 1;

end.


Fehlermeldung "Label declared and referenced, but not set: '<label>' "
"Label declared and referenced, but not set: '<label>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben ein Label in Ihrem Programm deklariert und verwendet, aber die Label-Definition wurde nicht im Quellcode gefunden.


Beispiele

{ Label 10 wird in der Prozedur 'Labeled' deklariert und verwendet, aber der Compiler kann keine Definition des Labels finden. }

  program Produce;

    procedure Labeled;

    label 10;

    begin

      goto 10;

    end;

  begin

  end.

{ Die einfache Lösung liegt darin, darauf zu achten, daß für ein deklariertes und verwendetes Label in Ihrem Programm und im gleichen Gültigkeitsbereich eine Definition besteht. }

  program Produce;

    procedure Labeled;

    label 10;

    begin

      goto 10;

      10:

    end;

  begin

  end.


Fehlermeldung "This form of method call only allowed in methods of derived types "
"This form of method call only allowed in methods of derived types"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, eine Methode eines Vorgänger-Typs aufzurufen, sich aber tatsächlich nicht innerhalb einer Methode befinden.


Beispiele

{ Im nachstehenden Beispiel wird versucht, einen vererbten Konstruktor in der Prozedur Create aufzurufen, bei der es sich nicht um eine Methode handelt. }

program Produce;

type

  TMyClass = class

    constructor Create;

  end;

procedure Create;

begin

  inherited Create;      { <-- Hier die Fehlermeldung }

end;

begin

end.

{ Die Lösung liegt darin, darauf zu achten, daß Sie sich tatsächlich innerhalb einer Methode befinden, wenn Sie diese Art Aufruf verwenden. }

program Solve;

type

  TMyClass = class

    constructor Create;

  end;

constructor TMyclass.Create;

begin

  inherited Create;

end;

begin

end.


Fehlermeldung "This form of method call only allowed for class methods "
"This form of method call only allowed for class methods"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Sie haben versucht, eine normale Methode aufzurufen, wobei Sie nur den Klassentyp angegeben haben, keine Instanz. Dies ist nur bei Klassenmethoden und Konstruktoren zulässig, nicht bei normalen Methoden und Destruktoren.


Beispiele

{ Im nachstehenden Beispiel wird versucht, den Typ TMyClass zu zerstören - dies ist sinnlos und daher unzulässig. }

program Produce;

type

  TMyClass = class

    { ... }

  end;

var

  MyClass: TMyClass;

begin

  MyClass := TMyClass.Create;  { In Ordnung, Konstruktor }

  Writeln(TMyClass.ClassName); { In Ordnung, Klassenmethode }

  TMyClass.Destroy;            { <-- Hier die Fehlermeldung }

end.

{ Offensichtlich wollten wir eigentlich die Instanz des Typs zerstören, nicht den Typ selbst. }

program Solve;

type

  TMyClass = class

    { ... }

  end;

var

  MyClass: TMyClass;

begin

  MyClass := TMyClass.Create;  { In Ordnung, Konstruktor }

  Writeln(TMyClass.ClassName); { In Ordnung, Klassenmethode }

  MyClass.Destroy;             { In Ordnung, Instanz aufgerufen }

end.


Fehlermeldung "Incompatible types: <text> "
"Incompatible types: <text>"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler hat einen Unterschied zwischen der Deklarierung und der Verwendung einer Prozedur entdeckt.


Beispiele

{ Der Aufruf von 'TakesParm0' löst einen Fehler aus, weil der Typ 'ProcedureParm0' eine Prozedur 'stdcall' erwartet, während 'WrongConvention' mit der Aufrufkonvention 'register' deklariert wurde. Außerdem wird der Aufruf von 'TakesParm1' fehlschlagen, weil die Parameterlisten nicht übereinstimmen. }

program Produce;

  type

    ProcedureParm0 = procedure; stdcall;

    ProcedureParm1 = procedure(var X: Integer);

  procedure WrongConvention; register;

  begin

  end;

  procedure WrongParms(x, y, z: Integer);

  begin

  end;

  procedure TakesParm0(p: ProcedureParm0);

  begin

  end;

  procedure TakesParm1(p: ProcedureParm1);

  begin

  end;

begin

  TakesParm0(WrongConvention);

  TakesParm1(WrongParms);

end.

{ Die Lösung für beide Probleme liegt einfach darin, darauf zu achten, daß die Aufrufkonvention bzw. die Parameterlisten mit der Deklarierung übereinstimmen. }

program Solve;

  type

    ProcedureParm0 = procedure; stdcall;

    ProcedureParm1 = procedure(var X: Integer);

  procedure RightConvention; stdcall;

  begin

  end;

  procedure RightParms(var X: Integer);

  begin

  end;

  procedure TakesParm0(p: ProcedureParm0);

  begin

  end;

  procedure TakesParm1(p: ProcedureParm1);

  begin

  end;

begin

  TakesParm0(RightConvention);

  TakesParm1(RightParms);

end.


Siehe auch

Prozedurentypen

Aufrufkonventionen


Warnmeldung "Variable '<name>' might not have been initialized "
"Variable '<name>' might not have been initialized"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird angezeigt, wenn einer Variablen nicht für jeden Programmcodepfad, in dem sie benutzt wird, ein Wert zugewiesen wurde.


Beispiele

{ In einer if-Anweisung müssen Sie darauf achten, daß der Variable in beiden Zweigen ein Wert zugewiesen wird. In einer Case-Anweisung müssen Sie einen else-Abschnitt hinzufügen, um sicherzustellen, daß der Variablen in jedem denkbaren Fall ein Wert zugewiesen wird. In einer try-except-Struktur geht der Compiler davon aus, daß Zuweisungen im try-Abschnitt in Wirklichkeit nicht vorgenommen werden, selbst wenn sie direkt am Anfang des try-Abschnittes stehen und so einfach sind, daß sie auf keinen Fall eine Ausnahme auslösen könnten. }

program Produce;

{$WARNINGS ON}

var

  B: Boolean;

  C: (Rot,Grün,Blau);

procedure Simple;

var

  I: Integer;

begin

  Writeln(I);        { <-- Hier die Warnmeldung }

end;

procedure IfStatement;

var

  I: Integer;

begin

  if B then

    I := 42;

  Writeln(I);        { <-- Hier die Warnmeldung }

end;

procedure CaseStatement;

var

  I: Integer;

begin

  case C of

  Rot..Blau: I := 42;

  end;

  Writeln(I);        { <-- Hier die Warnmeldung }

end;

procedure TryStatement;

var

  I: Integer;

begin

  try

    I := 42;

  except

    Writeln('Sollte gar nicht hier ankommen!');

  end;

  Writeln(I);        { <-- Hier die Warnmeldung }

end;

begin

  B := False;

end.

{ Die Lösung liegt darin, Zuweisungen zu den Programmcodepfaden an den entsprechenden Stellen bzw. eine Zuweisung vor einer bedingten Anweisung oder einer try-except-Struktur einzufügen. }

program Solve;

{$WARNINGS ON}

var

  B: Boolean;

  C: (Rot,Grün,Blau);

procedure Simple;

var

  I: Integer;

begin

  I := 42;

  Writeln(I);

end;

procedure IfStatement;

var

  I: Integer;

begin

  if B then

    I := 42

  else

    I := 0;

  Writeln(I);        { Für I muß im else-Abschnitt eine Zuweisung erfolgen }

end;

procedure CaseStatement;

var

  I: Integer;

begin

  case C of

  Rot..Blau: I := 42;

  else       I := 0;

  end;

  Writeln(I);        { Für I muß im else-Abschnitt eine Zuweisung erfolgen }

end;

procedure TryStatement;

var

  I: Integer;

begin

  I := 0;

  try

    I := 42;

  except

    Writeln('Sollte gar nicht hier ankommen!');

  end;

  Writeln(I);        { Für I muß eine Zuweisung vor dem try erfolgen }

end;

begin

  B := False;

end.


Hinweismeldung "Value assigned to '<name>' never used "
"Value assigned to '<name>' never used"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Compiler gibt diese Hinweismeldung aus, wenn der einer Variablen zugewiesene Wert nicht benutzt wird. Wenn die Optimierung aktiviert ist, wird die Zuweisung gelöscht. Dies kann vorkommen, wenn die Variable nicht mehr benutzt wird und wenn ihr vor der Verwendung ein neuer Wert zugewiesen wird.

Mit dieser Hinweismeldung wird nicht angedeutet, daß Ihr Programm fehlerhaft ist - sie bedeutet einfach, daß der Compiler festgestellt hat, daß es eine Zuweisung gibt, die nicht notwendig ist. In der Regel können Sie diese Zuweisung einfach löschen - sie wird im compilierten Programmcode ohnehin fallengelassen, wenn Sie die Compilierung bei aktivierter Optimierung durchführen. In  manchen Fällen liegt das wirkliche Problem allerdings darin, daß Sie eine Zuweisung zur falschen Variable durchgeführt haben, also beispielsweise eine Zuweisung zu J durchführen wollten, aber tatsächlich eine Zuweisung zu I vorgenommen haben. Es ist also die Mühe wert, die fragliche Zuweisung sorgfältig zu überprüfen.


Beispiele

{ In der Prozedur Propagate ist der Compiler schlau genug, um zu erkennen, daß die Variable I nicht innerhalb der while-Schleife inkrementiert werden muß, weil I danach gar nicht mehr benutzt wird, und daß daher die Inkrementierung und die Zuweisung vor der while-Schleife ebenfalls überflüssig sind. In der Prozedur TryFinally ist die Zuweisung zu I vor der try-finally-Struktur nicht notwendig. Wenn eine Ausnahme auftritt, wird die Writeln-Anweisung am Ende nicht ausgeführt, so daß der Wert von I keine Rolle spielt. Tritt keine Ausnahme auf, ist der Wert von I für die Writeln-Anweisung immer gleich 42. Daher wird die erste Zuweisung das Verhalten der Prozedur nicht verändern und kann also gelöscht werden. }

program Produce;

{$HINTS ON}

procedure Simple;

var

  I: Integer;

begin

  I := 42;                { <-- Hier die Hinweismeldung }

end;

procedure Propagate;

var

  I: Integer;

  K: Integer;

begin

  I := 0;                 { <-- Hier die Hinweismeldung}

  Inc(I);                 { <-- Hier die Hinweismeldung}

  K := 42;

  while K > 0 do

  begin

    if Odd(K) then

      Inc(I);             { <-- Hier die Hinweismeldung}

    Dec(K);

  end;

end;

procedure TryFinally;

var

  I: Integer;

begin

  I := 0;                 { <-- Hier die Hinweismeldung}

  try

    I := 42;

  finally

    Writeln('Endlich angekommen');

  end;

  Writeln(I);             { Schreibt immer 42 - wenn eine Ausnahme auftreten würde,

                            kämen wir gar nicht hier an }

end;

begin

end.


Warnmeldung "Return value of function '<Functionname>' might be undefined "
"Return value of function '<Functionname>' might be undefined"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird ausgegeben, wenn dem Rückgabewert einer Funktion kein Wert für jeden Programmcodepfad zugewiesen wurde. Um es etwas anders auszudrücken: Die Funktion könnte so ausgeführt werden, daß niemals eine Zuweisung zum Rückgabewert erfolgt.


Beispiele

{ Das Problem mit der Prozedur IfStatement und CaseStatement liegt darin, daß zum Ergebnis nicht in allen Programmcodepfaden eine Zuweisung erfolgt. Bei TryStatement nimmt der Compiler an, daß eine Ausnahme ausgelöst werden könnte, bevor Result ein Wert zugewiesen wurde (in diesem Fall ist der Compiler offensichtlich zu konservativ). }

program Produce;

{$WARNINGS ON}

var

  B: Boolean;

  C: (Rot, Grün, Blau);

function Simple: Integer;

begin

end;                           { <-- Hier die Warnmeldung }

function IfStatement: Integer;

begin

  if B then

    Result := 42;

end;                           { <-- Hier die Warnmeldung }

function CaseStatement: Integer;

begin

  case C of

  Rot..Blau: Result := 42;

  end;

end;                           { <-- Hier die Warnmeldung }

function TryStatement: Integer;

begin

  try

    Result := 42;

  except

    Writeln('Sollte gar nicht hier ankommen!');

  end;

end;                           { <-- Hier die Warnmeldung }

begin

  B := False;

end.

{ Die Lösung liegt einfach darin, darauf zu achten, daß eine Zuweisung zur Ergebnisvariable in jedem möglichen Programmcodepfad erfolgt. }

program Solve;

{$WARNINGS ON}

var

  B: Boolean;

  C: (Rot, Grün, Blau);

function Simple: Integer;

begin

  Result := 42;

end;

function IfStatement: Integer;

begin

  if B then

    Result := 42

  else

    Result := 0;

end;

function CaseStatement: Integer;

begin

  case C of

  Rot..Blau: Result := 42;

  else       Result := 0;

  end;

end;

function TryStatement: Integer;

begin

  Result := 0;

  try

    Result := 42;

  except

    Writeln('Sollte gar nicht hier ankommen!');

  end;

end;

begin

  B := False;

end.


Fehlermeldung " Procedure FAIL only allowed in constructor "
" Procedure FAIL only allowed in constructor"

Compiler-Fehlermeldungen

Beschreibung

Die Standard-Prozedur Fail kann nur aus einem Konstruktor heraus aufgerufen werden - in allen anderen Fällen ist der Aufruf nicht zulässig.


Fehlermeldung " Procedure NEW needs constructor "
" Procedure NEW needs constructor"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn ein in der Parameterliste zu New angegebener Bezeichner kein Konstruktor ist.


Beispiele

${ Aus Versehen haben wir New mit dem Destruktor anstatt mit dem Konstruktor aufgerufen. }

program Produce;

type

  PMyObject = ^TMyObject;

  TMyObject = object

    F: Integer;

    constructor Init;

    destructor Done;

  end;

constructor TMyObject.Init;

begin

  F := 42;

end;

destructor TMyObject.Done;

begin

end;

var

  P: PMyObject;

begin

  New(P, Done);              { <-- Hier die Fehlermeldung }

end.

{ Achten Sie darauf, daß Sie der Standard-Funktion New entweder einen Konstruktor oder überhaupt kein zusätzliches Argument angeben. }

program Solve;

type

  PMyObject = ^TMyObject;

  TMyObject = object

    F: Integer;

    constructor Init;

    destructor Done;

  end;

constructor TMyObject.Init;

begin

  F := 42;

end;

destructor TMyObject.Done;

begin

end;

var

  P: PMyObject;

begin

  New(P, Init);

end.


Fehlermeldung "Procedure DISPOSE needs destructor "
"Procedure DISPOSE needs destructor"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn ein in der Parameterliste zu Dispose angegebener Bezeichner kein Destruktor ist.


Beispiele

{ In diesem Beispiel haben wir Dispose aus Versehen den Konstruktor übergeben. }

program Produce;

type

  PMyObject = ^TMyObject;

  TMyObject = object

    F: Integer;

    constructor Init;

    destructor Done;

  end;

constructor TMyObject.Init;

begin

  F := 42;

end;

destructor TMyObject.Done;

begin

end;

var

  P: PMyObject;

begin

  New(P, Init);

  { ... }

  Dispose(P, Init);        { <-- Hier die Fehlermeldung }

end.

{ Die Lösung liegt darin, Dispose einen Destruktor zu übergeben oder das zweite Argument zu löschen. }

program Solve;

type

  PMyObject = ^TMyObject;

  TMyObject = object

    F: Integer;

    constructor Init;

    destructor Done;

  end;

constructor TMyObject.Init;

begin

  F := 42;

end;

destructor TMyObject.Done;

begin

end;

var

  P: PMyObject;

begin

  New(P, Init);

  Dispose(P, Done);

end.


Fehlermeldung "Assignment to FOR-Loop variable '<name>' "
"Assignment to FOR-Loop variable '<name>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Es ist nicht zulässig, der Steuervariable der for-Schleife einen Wert innerhalb der for-Schleife zuzuweisen. Wenn Sie die Schleife vorzeitig verlassen möchten, verwenden Sie die Break- oder die goto-Anweisung.


Beispiele

{ In diesem Fall glaubte der Programmierer, daß die Zuweisung von 99 zu I das Programm zum Verlassen der Schleife bewegen würde. }

program Produce;

var

  I: Integer;

  A: array[0..99] of Integer;

begin

  for I := 0 to 99 do

begin

    if A[I] = 42 then

      I := 99;

  end;

end.

{ Die Verwendung einer break-Anweisung ist eine sauberere Vorgehensweise zum Verlassen einer for-Schleife. }

program Solve;

var

  I: Integer;

  A: array[0..99] of Integer;

begin

  for I := 0 to 99 do

begin

    if A[I] = 42 then

      Break;

  end;

end.


Warnmeldung "FOR-Loop variable '<name>' may be undefined after loop "
"FOR-Loop variable '<name>' may be undefined after loop"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird ausgegeben, wenn der Wert der Steuervariable einer for-Schleife nach Beendigung der Schleife verwendet wird. Sie können sich auf den Endwert der Steuervariablen einer for-Schleife nur dann verlassen, wenn die Schleife mit der Anweisung goto oder Exit verlassen wurde. Der Zweck dieser Einschränkung liegt darin, dem Compiler die Erzeugung eines leistungsfähigen Programmcodes für die for-Schleife zu ermöglichen.


Beispiele

{ In diesem Beispiel wird die Variable Result implizit nach Beendigung der Schleife verwendet, aber sie ist nicht definiert, wenn wir den Wert nicht finden würden - daher die Warnmeldung. }

program Produce;

{$WARNINGS ON}

function Search(const A: array of Integer; Value: Integer): Integer;

begin

  for Result := 0 to High(A) do

    if A[Result] = Value then

      Break;

end;

const

  A: array[0..9] of Integer = (1,2,3,4,5,6,7,8,9,10);

begin

  Writeln( Search(A,11) );

end.

{ Die Lösung liegt darin, der Steuervariable einfach den gewünschten Wert zuzuweisen für den Fall, daß wir die Schleife nicht vorzeitig verlassen. }

program Solve;

{$WARNINGS ON}

function Search(const A: array of Integer; Value: Integer): Integer;

begin

  for Result := 0 to High(A) do

    if A[Result] = Value then

      Exit;

  Result := High(A)+1;

end;

const

  A: array[0..9] of Integer = (1,2,3,4,5,6,7,8,9,10);

begin

  Writeln( Search(A,11) );

end.


Fehlermeldung "TYPEOF can only be applied to object types with a VMT "
"TYPEOF can only be applied to object types with a VMT"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, die Standard-Funktion TypeOf auf einen Objekttypen anzuwenden, der nicht über eine Tabelle mit virtuellen Methoden verfügt. Ein einfacher Umweg ist die Deklarierung einer virtuellen Dummy-Methode, um den Compiler zur Erzeugung einer VMT zu zwingen.


Beispiele

{ Im nachstehenden Beispiel wird versucht, die Standard-Funktion TypeOf auf den Typ TMyObject anzuwenden, der keine virtuellen Funktionen und daher auch keine Tabelle mit virtuellen Funktionen (VMT) besitzt. }

program Produce;

type

  TMyObject = object

    procedure MyProc;

  end;

procedure TMyObject.MyProc;

begin

  { ... }

end;

var

  P: Pointer;

begin

  P := TypeOf(TMyObject);    { <-- Hier die Fehlermeldung }

end.

{ Die Lösung liegt darin, einfach eine virtuelle Dummy-Funktion einzuführen oder den Aufruf von TypeOf zu löschen. }

program Solve;

type

  TMyObject = object

    procedure MyProc;

    procedure Dummy; virtual;

  end;

procedure TMyObject.MyProc;

begin

  { ... }

end;

procedure TMyObject.Dummy;

begin

end;

var

  P: Pointer;

begin

  P := TypeOf(TMyObject);

end.


Fehlermeldung "Order of fields in record constant differs from declaration r Deklarierung"
"Order of fields in record constant differs from declaration r Deklarierung"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung erscheint, wenn Datensatzfelder in einer typisierten Konstante oder einer initialisierten Variable nicht in der Reihenfolge der Deklarierung initialisiert werden.


Beispiele

{ Im nachstehenden Beispiel wird versucht, zuerst Y und dann X zu deklarieren, also in der umgekehrten Reihenfolge wie bei der Deklarierung. }

program Produce;

type

  TPoint = record

    X, Y: Integer;

  end;

var

  Point: TPoint = (Y: 123; X: 456);

begin

end.

{ Die Lösung liegt einfach darin, die Reihenfolge der Initialisierung so zu ändern, daß sie der Reihenfolge bei der Deklarierung entspricht. }

program Solve;

type

  TPoint = record

    X, Y: Integer;

  end;

var

  Point: TPoint = (X: 456; Y: 123);

begin

end.


Fehlermeldung "Incompatible types: '<name>' and '<name>' "
"Incompatible types: '<name>' and '<name>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung tritt auf, wenn der Compiler zwei Typen als kompatibel miteinander erwartet hat (d. h. sehr ähnlich zueinander), sie sich aber als unterschiedlich herausgestellt haben.


Beispiele

{ Hier hat ein C++-Programmierer geglaubt, daß der Divisionsoperator / ein integrales Ergebnis liefern würde - trifft bei Pascal nicht zu. }

program Produce;

procedure Proc(I: Integer);

begin

end;

begin

  Proc( 22 / 7 ); { Ergebnis des Operators / ist reell }

end.

{ Die Lösung in diesem Fall liegt darin, den Operator für integrale Division div zu benutzen - im allgemeinen müssen Sie Ihr Programm sehr gründlich betrachten, um entscheiden zu können, wie Typ-Inkompatibilitäten zu beheben sind. }

program Solve;

procedure Proc(I: Integer);

begin

end;

begin

  Proc( 22 div 7 ); { Der Operator div führt zu einem Ergebnis vom Typ Integer }

end.


Fehlermeldung "Internal error: <ErrorCode> "
"Internal error: <ErrorCode>"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung sollten Sie niemals erhalten - sie bedeutet, daß ein Programmierungsfehler im Compiler vorliegt. Wenn diese Fehlermeldung angezeigt wird, wenden Sie sich bitte an Borland Tech Support, und geben Sie uns den ErrorCode durch (beispielsweise "C1196"), der in der Fehlermeldung erscheint. Auf diese Weise erhalten wir einen groben Überblick über das, was nicht ordnungsgemäß funktioniert hat. Es wäre sogar noch hilfreicher, wenn Sie uns ein Beispielprogramm übermitteln könnten, das die Fehlermeldung ausgelöst hat.


Fehlermeldung "Unit name mismatch: '<Unitname>' "
"Unit name mismatch: '<Unitname>'"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Der Bezeichner der Unit stimmt nicht mit dem Unit-Dateinamen überein. Dies kann bei der Mischung von langen Dateinamen und kürzeren Unit-Bezeichnern geschehen.


Beispiele

{ In diesem Fall liegt das Problem darin, daß der Compiler die falsche Unit gefunden hat, weil die Dateinamen auf 8 Zeichen gekürzt worden sind. }

----- Contents of MY_UNIT_.PAS ---------------------------------------------

unit My_Unit_With_A_Long_Name;

interface

implementation

end.

----- End of MY_UNIT_.PAS --------------------------------------------------

program Produce;

uses My_Unit_With_Another_Long_Name; { Findet MY_UNIT_.PAS, falls der Befehlszeilenschalter -P

       aktiv ist - aber es ist die falsche Unit. }

begin

end.

{ Die Lösung liegt darin, lange Dateinamen zu benutzen oder darauf zu achten, daß die ersten 8 Zeichen der Dateinamen unterschiedlich sind. Außerdem müssen Sie darauf achten, daß der Dateiname einer Unit mit der Unit-Bezeichnung übereinstimmt. }


Fehlermeldung "Keine Bezeichner referenziert von Unit <Unitname>"
"Keine Bezeichner referenziert von Unit <Unitname>"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird zur Zeit nicht benutzt.


Fehlermeldung "Type '<name>' is not yet completely defined "
"Type '<name>' is not yet completely defined"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Dieser Fehler tritt auf, wenn ein Bezug auf einen Typ vorgenommen wird, der gerade definiert wird, oder wenn in einem Typabschnitt ein forward-deklarierter Klassentyp steht, für den keine endgültige Deklarierung existiert.


Beispiele

{ Im nachstehenden Beispiel wird versucht, einen Bezug auf einen Datensatztyp herzustellen, bevor er vollständig definiert wurde. Außerdem findet der Compiler aufgrund eines Schreibfehlers niemals eine vollständige Deklarierung für TMyClass. }

program Produce;

type

  TListEntry = record

    Next: ^TListEntry;                      { <-- Hier die Fehlermeldung }

    Data: Integer;

  end;

  TMyClass = class;                         { <-- Hier die Fehlermeldung }

  TMyClassRef = class of TMyClass;

  TMyClasss = class                         { <-- Typo ... }

    { ... }

  end;

begin

end.

{ Die Lösung für das erste Problem ist die Einführung einer Typdeklarierung für einen zusätzlichen Zeigertyp. Das zweite Problem wird behoben, indem die Schreibweise von TMyClass berichtigt wird. }

program Solve;

type

  PListEntry = ^TListEntry;

  TListEntry = record

    Next: PListEntry;

    Data: Integer;

  end;

  TMyClass = class;

  TMyClassRef = class of TMyClass;

  TMyClass = class

    { ... }

  end;

begin

end.


Fehlermeldung "Diese Demo-Version wurde verändert"
"Diese Demo-Version wurde verändert"

Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird zur Zeit nicht benutzt.


Fehlermeldung "Integer constant or variable name expected "
"Integer constant or variable name expected"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird angezeigt, wenn Sie versuchen, eine absolute Variable zu deklarieren, aber nach der Anweisung absolute weder eine ganzzahlige Konstante noch eine Variablenbezeichnung steht.


Beispiele

program Produce;

var

  I: Integer;

  J: Integer absolute Addr(I);   { <-- Hier die Fehlermeldung }

begin

end.

program Solve;

const

  Addr = 0;

var

  I: Integer;

  J: Integer absolute I;

begin

end.


Fehlermeldung "Invalid typecast "
"Invalid typecast"

Siehe auch	Beispiele	Compiler-Fehlermeldungen

Beschreibung

Diese Fehlermeldung wird bei Typumwandlungen angezeigt, die den Regeln gemäß nicht zulässig sind.

Die folgenden Typumwandlungsarten sind zulässig:

Ordinal oder Zeigertyp in ein anderes Ordinal oder einen anderen Zeigertyp

Ein Zeichen, String, Array mit Zeichen oder pchar in einen String

Ein Ordinal, eine reelle Zahl, ein String oder eine Variante in eine Variante

Eine Variante in ein Ordinal, eine reelle Zahl, einen String oder eine Variante

Ein Variablenbezug in einen beliebigen Typ mit der gleichen Größe

Beachten Sie, daß die Umwandlung von reellen Typen in ganzzahlige Typen mit den Standard-Funktionen Trunc und Round durchgeführt werden kann. Es stehen weitere Transfer-Funktionen wie Ord und Chr zur Verfügung, mit denen Ihre Absicht deutlicher gemacht werden kann.


Beispiele

{ Dieser Programmierer glaubte, er könnte wie bei C eine Gleitkommazahl in eine ganze Zahl umwandeln. }

program Produce;

begin

  Writeln( Integer(Pi) );

end.

{ In Pascal gibt es getrennte Transfer-Funktionen für die Konvertierung von Gleitkommawerten in ganze Zahlen. }

program Solve;

begin

  Writeln( Trunc(Pi) );

end.


Siehe auch

Typumwandlung, Transfer-Routinen, Trunc, Round, Chr, Ord


Meldung "Benutzerunterbrechung - Compilierung abgebrochen"
"Benutzerunterbrechung - Compilierung abgebrochen"

Compiler-Fehlermeldungen

Beschreibung

Diese Meldung wird zur Zeit nicht benutzt.


Warnmeldung "Anweisung für typisierte Konstante '<Name>'"
"Anweisung für typisierte Konstante '<Name>'"

Compiler-Fehlermeldungen

Beschreibung

Diese Warnmeldung wird zur Zeit nicht benutzt.


Fehlermeldung "Segment/Offset pairs not supported in Borland 32-bit Pascal "
"Segment/Offset pairs not supported in Borland 32-bit Pascal"

Beispiele	Compiler-Fehlermeldungen

Beschreibung

Im 32-Bit-Programmcode wird das im 16-Bit-Programmcode eingesetzte Segment/Offset-Adressierungsverfahren nicht mehr verwendet. In den 16-Bit-Versionen von Borland Pascal wurden Segment/Offset-Paare für die Deklarierung absoluter Variablen verwendet und als Argumente für die Standard-Funktion Ptr benutzt.

Beachten Sie, daß absolute Adressen nicht in 32-Bit-Programmen im geschützten Modus verwendet werden sollten. Statt dessen sollten geeignete Win32-API-Funktionen aufgerufen werden.


Beispiele

program Produce;

var

  VideoMode: Integer absolute $0040:$0049;

begin

  Writeln( Byte(Ptr($0040,$0049)^) );

end.

program Solve;

{ Diese Version wird compiliert, ist aber nicht lauffähig - absolute Adressen sind uncool }

var

  VideoMode: Integer absolute $0040*16+$0049;

begin

  Writeln( Byte(Ptr($0040*16+$0049)^) );

end.


Laufzeitfehler

Beim Auftreten bestimmter Fehler während der Laufzeit gibt das Programm eine Fehlermeldung aus und bricht die Ausführung ab:

Run-time error nnn at xxxxxxxx

nnn gibt hierbei die Nummer des Laufzeitfehlers an, xxxxxxxx entspricht der Adresse, an der er aufgetreten ist.

Delphi-Anwendungen, die die Unit SysUtils  benutzen, führen ein Mapping der meisten Laufzeitfehler auf Ausnahmen durch; auf diese Weise wird Ihre Anwendung in die Lage versetzt, den Fehler ohne Abbruch zu beheben. Dies wird als Ausnahmenbehandlung bezeichnet.

Die Laufzeitfehler werden in drei Kategorien eingeteilt:

I/O-Fehler, Numerierung von 100 bis 149

schwere Fehler, Numerierung von 200 bis 255

Betriebssystemfehler

I/O-Fehler

Diese Fehler führen zum Abbruch, wenn die fragliche Anweisung im Zustand {$I+} compiliert wurde. Im Zustand {$I-} wird die Ausführung des Programms fortgesetzt, und der Fehler wird von der Funktion IOResult gemeldet.

 Nummer	Bezeichnung	Beschreibung

100	Festplattenlesefehler	Wird von Read für eine typisierte Datei gemeldet, wenn Sie versuchen, über das Ende der Datei hinaus zu lesen.

101	Festplattenschreibfehler	Wird von CloseFile, Write, Writeln, oder Flush gemeldet, wenn die Kapazität der Festplatte erschöpft ist.

102	Keine Zuweisung zur Datei	Wird von Reset, Rewrite, Append, Rename, und Erase gemeldet, wenn der Dateivariable keine Bezeichnung durch einen Aufruf von Assign oder AssignFile zugewiesen wurde.

103	Datei nicht geöffnet	Wird von CloseFile, Read, Write, Seek, Eof, FilePos, FileSize, Flush, BlockRead, oder BlockWrite gemeldet, wenn die Datei nicht geöffnet ist.

104	Datei nicht für Eingabe geöffnet	Wird von Read, Readln, Eof, Eoln, SeekEof, oder SeekEoln für eine Textdatei gemeldet, wenn die Datei nicht für eine Eingabe geöffnet ist.

105	Datei nicht für Ausgabe geöffnet	Wird von Write und Writeln für eine Textdatei gemeldet, wenn Sie keine Console-Anwendung erstellen.

106	Ungültiges numerisches Format	Wird von Read oder Readln gemeldet, wenn ein numerischer Wert aus einer Textdatei nicht dem ordnungsgemäßen numerischen Format entspricht.

Schwere Fehler

Das Auftreten dieser Fehler führt immer zum sofortigen Abbruch des Programms.

Bei Anwendungen, die die Unit SysUtils benutzen (wie die meisten Delphi-Anwendungen) wird für diese Fehler ein Mapping auf Ausnahmen durchgeführt. Eine ausführlichere Beschreibung der Fehlerbedingungen, durch die ein Fehler erzeugt wird, finden Sie in den Erläuterungen zu den Ausnahmen.

Nummer	Bezeichnung	Ausnahme

200	Division durch Null	EDivByZero

201	Bereichsüberschreitung	ERangeError

202	Stack-Überlauf	EStackOverflow

203	Heap-Überlauf	EOutOfMemory

204	Ungültige Zeiger-Operation	EInvalidPointer

205	Überlauf bei Gleitkomma-Operation	EOverflow

206	Unterlauf bei Gleitkomma-Operation	EUnderflow

207	Fehler bei Gleitkomma-Operation	EInvalidOp

215	Arithmetischer Fehler	EIntOverflow

216	Zugriffsverletzung	EAccessViolation

217	Strg-C	EControlC

218	Priviligierte Instruktion	EPrivilege

219	Ungültige Typumwandlung	EInvalidCast

220	Ungültige Varianten-Typumwandlung	EVariantError

221	Ungültige Varianten-Operation	EVariantError

222	Kein Dispatcher für Varianten-Aufruf	EVariantError

223	Varianten-Array kann nicht erstellt

werden	EVariantError

224	Variante enthält kein Array	EVariantError

225	Fehler bei den Grenzen des

Varianten-Arrays	EVariantError

226	Fehler bei der TLS-Initialisierung

Betriebssystemfehler

Alle Fehler mit Ausnahme der I/O-Fehler und der schweren Fehler werden mit der von der Win32-Fehlerfunktion GetLastError zurückgegebenen Fehlercode gemeldet. Die Werte des Fehlercodes hängen vom jeweiligen Betriebssystem ab, aber in der Win32-Dokumentation finden Sie eine Liste dieser Werte.